From e3bbeb7fdc5d3403944a8598abb4fb0aacee6169 Mon Sep 17 00:00:00 2001 From: Thomas A Date: Sun, 26 Jun 2022 09:13:52 -0700 Subject: [PATCH] Update libcxx source to llvmorg-14.0.6 --- CMakeLists.txt.old | 913 +- CREDITS.TXT | 58 +- NOTES.TXT | 29 - TODO.TXT | 53 - benchmarks/CMakeLists.txt | 119 +- benchmarks/CartesianBenchmarks.h | 1 - benchmarks/GenerateInput.h | 9 +- benchmarks/VariantBenchmarks.h | 58 + benchmarks/algorithms.bench.cpp | 219 +- .../algorithms.partition_point.bench.cpp | 2 +- benchmarks/allocation.bench.cpp | 1 - benchmarks/deque.bench.cpp | 1 - benchmarks/filesystem.bench.cpp | 6 +- benchmarks/format.bench.cpp | 36 + benchmarks/format_to.bench.cpp | 107 + benchmarks/format_to_n.bench.cpp | 107 + benchmarks/formatted_size.bench.cpp | 36 + benchmarks/formatter_float.bench.cpp | 241 + benchmarks/map.bench.cpp | 1037 ++ .../std_format_spec_string_unicode.bench.cpp | 196 + benchmarks/string.bench.cpp | 181 + benchmarks/to_chars.bench.cpp | 58 + benchmarks/unordered_set_operations.bench.cpp | 4 +- benchmarks/variant_visit_1.bench.cpp | 27 + benchmarks/variant_visit_2.bench.cpp | 22 + benchmarks/variant_visit_3.bench.cpp | 20 + cmake/Modules/CheckLibcxxAtomic.cmake | 56 - cmake/Modules/DefineLinkerScript.cmake | 16 +- cmake/Modules/HandleCompilerRT.cmake | 64 - cmake/Modules/HandleLibCXXABI.cmake | 62 +- cmake/Modules/HandleLibcxxFlags.cmake | 14 +- cmake/Modules/HandleOutOfTreeLLVM.cmake | 142 - cmake/caches/AArch64.cmake | 2 + cmake/caches/AIX.cmake | 16 + cmake/caches/Apple.cmake | 24 +- cmake/caches/Armv7Arm.cmake | 4 + cmake/caches/Armv7Thumb-noexceptions.cmake | 6 + cmake/caches/Armv8Arm.cmake | 4 + cmake/caches/Armv8Thumb-noexceptions.cmake | 6 + cmake/caches/FreeBSD.cmake | 9 + cmake/caches/Generic-asan.cmake | 3 + cmake/caches/Generic-assertions.cmake | 1 + cmake/caches/Generic-cxx03.cmake | 2 + cmake/caches/Generic-cxx11.cmake | 2 + cmake/caches/Generic-cxx14.cmake | 2 + cmake/caches/Generic-cxx17.cmake | 2 + cmake/caches/Generic-cxx20.cmake | 2 + cmake/caches/Generic-cxx2b.cmake | 2 + cmake/caches/Generic-debug-iterators.cmake | 2 + cmake/caches/Generic-modules.cmake | 2 + cmake/caches/Generic-msan.cmake | 1 + cmake/caches/Generic-no-debug.cmake | 1 + cmake/caches/Generic-no-experimental.cmake | 2 + cmake/caches/Generic-no-filesystem.cmake | 1 + cmake/caches/Generic-no-localization.cmake | 1 + cmake/caches/Generic-no-random_device.cmake | 1 + cmake/caches/Generic-no-unicode.cmake | 1 + cmake/caches/Generic-no-wide-characters.cmake | 1 + cmake/caches/Generic-noexceptions.cmake | 2 + cmake/caches/Generic-singlethreaded.cmake | 3 + cmake/caches/Generic-static.cmake | 3 + cmake/caches/Generic-tsan.cmake | 1 + cmake/caches/Generic-ubsan.cmake | 2 + cmake/caches/MinGW.cmake | 18 + cmake/caches/README.md | 13 + cmake/config-ix.cmake | 65 +- docs/AddingNewCIJobs.rst | 66 + docs/BuildingLibcxx.rst | 363 +- docs/Contributing.rst | 181 + docs/DesignDocs/ABIVersioning.rst | 27 +- docs/DesignDocs/AtomicDesign.rst | 797 ++ docs/DesignDocs/AvailabilityMarkup.rst | 105 - docs/DesignDocs/CapturingConfigInfo.rst | 6 +- docs/DesignDocs/DebugMode.rst | 106 +- docs/DesignDocs/FeatureTestMacros.rst | 8 +- docs/DesignDocs/FileTimeType.rst | 2 +- docs/DesignDocs/NoexceptPolicy.rst | 13 + docs/DesignDocs/UniquePtrTrivialAbi.rst | 149 + .../UnspecifiedBehaviorRandomization.rst | 86 + docs/DesignDocs/VisibilityMacros.rst | 12 +- docs/FeatureTestMacroTable.rst | 317 +- docs/Helpers/Styles.rst | 51 + docs/Makefile.sphinx | 37 - docs/README.txt | 4 + docs/ReleaseNotes.rst | 214 +- docs/Status/Cxx14.rst | 50 + docs/Status/Cxx14Issues.csv | 157 + docs/Status/Cxx14Papers.csv | 32 + docs/Status/Cxx17.rst | 55 + docs/Status/Cxx17Issues.csv | 318 + docs/Status/Cxx17Papers.csv | 113 + docs/Status/Cxx20.rst | 58 + docs/Status/Cxx20Issues.csv | 300 + docs/Status/Cxx20Papers.csv | 207 + docs/Status/Cxx2b.rst | 48 + docs/Status/Cxx2bIssues.csv | 141 + docs/Status/Cxx2bPapers.csv | 40 + docs/Status/Format.rst | 49 + docs/Status/FormatIssues.csv | 10 + docs/Status/FormatPaper.csv | 49 + docs/Status/Ranges.rst | 56 + docs/Status/RangesAlgorithms.csv | 100 + docs/Status/RangesIssues.csv | 33 + docs/Status/RangesPaper.csv | 159 + docs/Status/Spaceship.rst | 53 + docs/Status/SpaceshipPapers.csv | 10 + docs/Status/SpaceshipProjects.csv | 82 + docs/Status/Zip.rst | 29 + docs/Status/ZipProjects.csv | 27 + docs/TestingLibcxx.rst | 181 +- docs/UsingLibcxx.rst | 253 +- docs/conf.py | 9 +- docs/index.rst | 133 +- fuzzing/RoutineNames.txt | 20 - fuzzing/fuzz_test.cpp | 194 - fuzzing/fuzzing.cpp | 617 - fuzzing/fuzzing.h | 61 - include/CMakeLists.txt | 520 +- include/__algorithm/adjacent_find.h | 46 + include/__algorithm/all_of.h | 32 + include/__algorithm/any_of.h | 32 + include/__algorithm/binary_search.h | 55 + include/__algorithm/clamp.h | 46 + include/__algorithm/comp.h | 92 + include/__algorithm/comp_ref_type.h | 85 + include/__algorithm/copy.h | 77 + include/__algorithm/copy_backward.h | 79 + include/__algorithm/copy_if.h | 39 + include/__algorithm/copy_n.h | 66 + include/__algorithm/count.h | 35 + include/__algorithm/count_if.h | 35 + include/__algorithm/equal.h | 85 + include/__algorithm/equal_range.h | 82 + include/__algorithm/fill.h | 50 + include/__algorithm/fill_n.h | 42 + include/__algorithm/find.h | 32 + include/__algorithm/find_end.h | 150 + include/__algorithm/find_first_of.h | 52 + include/__algorithm/find_if.h | 32 + include/__algorithm/find_if_not.h | 32 + include/__algorithm/for_each.h | 32 + include/__algorithm/for_each_n.h | 42 + include/__algorithm/generate.h | 31 + include/__algorithm/generate_n.h | 35 + include/__algorithm/half_positive.h | 49 + include/__algorithm/in_in_out_result.h | 54 + include/__algorithm/in_in_result.h | 51 + include/__algorithm/in_out_result.h | 54 + include/__algorithm/includes.h | 62 + include/__algorithm/inplace_merge.h | 231 + include/__algorithm/is_heap.h | 45 + include/__algorithm/is_heap_until.h | 67 + include/__algorithm/is_partitioned.h | 38 + include/__algorithm/is_permutation.h | 162 + include/__algorithm/is_sorted.h | 45 + include/__algorithm/is_sorted_until.h | 57 + include/__algorithm/iter_swap.h | 32 + include/__algorithm/lexicographical_compare.h | 63 + include/__algorithm/lower_bound.h | 66 + include/__algorithm/make_heap.h | 59 + include/__algorithm/max.h | 72 + include/__algorithm/max_element.h | 58 + include/__algorithm/merge.h | 71 + include/__algorithm/min.h | 72 + include/__algorithm/min_element.h | 57 + include/__algorithm/minmax.h | 95 + include/__algorithm/minmax_element.h | 85 + include/__algorithm/mismatch.h | 67 + include/__algorithm/move.h | 78 + include/__algorithm/move_backward.h | 79 + include/__algorithm/next_permutation.h | 72 + include/__algorithm/none_of.h | 32 + include/__algorithm/nth_element.h | 248 + include/__algorithm/partial_sort.h | 74 + include/__algorithm/partial_sort_copy.h | 71 + include/__algorithm/partition.h | 81 + include/__algorithm/partition_copy.h | 47 + include/__algorithm/partition_point.h | 46 + include/__algorithm/pop_heap.h | 57 + include/__algorithm/prev_permutation.h | 72 + include/__algorithm/push_heap.h | 70 + include/__algorithm/remove.h | 45 + include/__algorithm/remove_copy.h | 38 + include/__algorithm/remove_copy_if.h | 38 + include/__algorithm/remove_if.h | 44 + include/__algorithm/replace.h | 32 + include/__algorithm/replace_copy.h | 36 + include/__algorithm/replace_copy_if.h | 36 + include/__algorithm/replace_if.h | 32 + include/__algorithm/reverse.h | 56 + include/__algorithm/reverse_copy.h | 32 + include/__algorithm/rotate.h | 200 + include/__algorithm/rotate_copy.h | 31 + include/__algorithm/sample.h | 102 + include/__algorithm/search.h | 125 + include/__algorithm/search_n.h | 112 + include/__algorithm/set_difference.h | 72 + include/__algorithm/set_intersection.h | 69 + .../__algorithm/set_symmetric_difference.h | 77 + include/__algorithm/set_union.h | 72 + include/__algorithm/shift_left.h | 56 + include/__algorithm/shift_right.h | 102 + include/__algorithm/shuffle.h | 160 + include/__algorithm/sift_down.h | 78 + include/__algorithm/sort.h | 556 + include/__algorithm/sort_heap.h | 53 + include/__algorithm/stable_partition.h | 295 + include/__algorithm/stable_sort.h | 230 + include/__algorithm/swap_ranges.h | 32 + include/__algorithm/transform.h | 43 + include/__algorithm/unique.h | 56 + include/__algorithm/unique_copy.h | 107 + include/__algorithm/unwrap_iter.h | 84 + include/__algorithm/upper_bound.h | 66 + include/__availability | 277 + include/__bit/bit_cast.h | 38 + include/__bit/byteswap.h | 55 + include/__bit_reference | 69 +- include/__bits | 145 + include/__bsd_locale_defaults.h | 2 +- include/__bsd_locale_fallbacks.h | 16 +- include/__charconv/chars_format.h | 77 + include/__charconv/from_chars_result.h | 37 + include/__charconv/to_chars_result.h | 37 + include/__chrono/calendar.h | 1276 ++ include/__chrono/convert_to_timespec.h | 55 + include/__chrono/duration.h | 615 + include/__chrono/file_clock.h | 85 + include/__chrono/high_resolution_clock.h | 36 + include/__chrono/steady_clock.h | 44 + include/__chrono/system_clock.h | 54 + include/__chrono/time_point.h | 249 + .../__compare/common_comparison_category.h | 94 + .../compare_partial_order_fallback.h | 73 + .../__compare/compare_strong_order_fallback.h | 70 + include/__compare/compare_three_way.h | 41 + include/__compare/compare_three_way_result.h | 43 + .../__compare/compare_weak_order_fallback.h | 70 + include/__compare/is_eq.h | 34 + include/__compare/ordering.h | 319 + include/__compare/partial_order.h | 71 + include/__compare/strong_order.h | 136 + include/__compare/synth_three_way.h | 51 + include/__compare/three_way_comparable.h | 58 + include/__compare/weak_order.h | 100 + include/__concepts/arithmetic.h | 48 + include/__concepts/assignable.h | 40 + include/__concepts/boolean_testable.h | 38 + include/__concepts/class_or_enum.h | 36 + include/__concepts/common_reference_with.h | 37 + include/__concepts/common_with.h | 47 + include/__concepts/constructible.h | 56 + include/__concepts/convertible_to.h | 37 + include/__concepts/copyable.h | 39 + include/__concepts/derived_from.h | 34 + include/__concepts/destructible.h | 32 + include/__concepts/different_from.h | 31 + include/__concepts/equality_comparable.h | 53 + include/__concepts/invocable.h | 41 + include/__concepts/movable.h | 39 + include/__concepts/predicate.h | 35 + include/__concepts/regular.h | 33 + include/__concepts/relation.h | 44 + include/__concepts/same_as.h | 35 + include/__concepts/semiregular.h | 33 + include/__concepts/swappable.h | 116 + include/__concepts/totally_ordered.h | 57 + include/__config | 848 +- include/__config_site.in | 14 +- include/__coroutine/coroutine_handle.h | 202 + include/__coroutine/coroutine_traits.h | 53 + include/__coroutine/noop_coroutine_handle.h | 112 + include/__coroutine/trivial_awaitables.h | 46 + include/__debug | 69 +- include/__errc | 4 +- include/__filesystem/copy_options.h | 80 + include/__filesystem/directory_entry.h | 511 + include/__filesystem/directory_iterator.h | 150 + include/__filesystem/directory_options.h | 78 + include/__filesystem/file_status.h | 68 + include/__filesystem/file_time_type.h | 27 + include/__filesystem/file_type.h | 39 + include/__filesystem/filesystem_error.h | 99 + include/__filesystem/operations.h | 197 + include/__filesystem/path.h | 1018 ++ include/__filesystem/path_iterator.h | 130 + include/__filesystem/perm_options.h | 73 + include/__filesystem/perms.h | 91 + .../recursive_directory_iterator.h | 181 + include/__filesystem/space_info.h | 35 + include/__filesystem/u8path.h | 96 + include/__format/format_arg.h | 292 + include/__format/format_args.h | 71 + include/__format/format_context.h | 165 + include/__format/format_error.h | 51 + include/__format/format_fwd.h | 56 + include/__format/format_parse_context.h | 109 + include/__format/format_string.h | 169 + include/__format/format_to_n_result.h | 41 + include/__format/formatter.h | 290 + include/__format/formatter_bool.h | 147 + include/__format/formatter_char.h | 104 + include/__format/formatter_floating_point.h | 717 + include/__format/formatter_integer.h | 170 + include/__format/formatter_integral.h | 463 + include/__format/formatter_pointer.h | 91 + include/__format/formatter_string.h | 162 + include/__format/parser_std_format_spec.h | 1398 ++ include/__functional/binary_function.h | 31 + include/__functional/binary_negate.h | 50 + include/__functional/bind.h | 392 + include/__functional/bind_back.h | 65 + include/__functional/bind_front.h | 58 + include/__functional/binder1st.h | 54 + include/__functional/binder2nd.h | 54 + include/__functional/compose.h | 52 + include/__functional/default_searcher.h | 56 + include/__functional/function.h | 2810 ++++ include/__functional/hash.h | 870 ++ include/__functional/identity.h | 37 + include/__functional/invoke.h | 100 + include/__functional/is_transparent.h | 36 + include/__functional/mem_fn.h | 161 + include/__functional/mem_fun_ref.h | 173 + include/__functional/not_fn.h | 53 + include/__functional/operations.h | 729 ++ include/__functional/perfect_forward.h | 95 + .../__functional/pointer_to_binary_function.h | 46 + .../__functional/pointer_to_unary_function.h | 46 + include/__functional/ranges_operations.h | 98 + include/__functional/reference_wrapper.h | 212 + include/__functional/unary_function.h | 29 + include/__functional/unary_negate.h | 47 + include/__functional/unwrap_ref.h | 57 + include/__functional/weak_result_type.h | 481 + include/__functional_03 | 1591 --- include/__functional_base | 642 +- include/__functional_base_03 | 223 - include/__hash_table | 370 +- include/__iterator/access.h | 129 + include/__iterator/advance.h | 199 + include/__iterator/back_insert_iterator.h | 70 + include/__iterator/common_iterator.h | 283 + include/__iterator/concepts.h | 264 + include/__iterator/counted_iterator.h | 303 + include/__iterator/data.h | 51 + include/__iterator/default_sentinel.h | 30 + include/__iterator/distance.h | 107 + include/__iterator/empty.h | 44 + include/__iterator/erase_if_container.h | 40 + include/__iterator/front_insert_iterator.h | 70 + include/__iterator/incrementable_traits.h | 72 + include/__iterator/indirectly_comparable.h | 30 + include/__iterator/insert_iterator.h | 81 + include/__iterator/istream_iterator.h | 92 + include/__iterator/istreambuf_iterator.h | 105 + include/__iterator/iter_move.h | 93 + include/__iterator/iter_swap.h | 106 + include/__iterator/iterator.h | 35 + include/__iterator/iterator_traits.h | 495 + include/__iterator/move_iterator.h | 185 + include/__iterator/next.h | 86 + include/__iterator/ostream_iterator.h | 70 + include/__iterator/ostreambuf_iterator.h | 76 + include/__iterator/prev.h | 78 + include/__iterator/projected.h | 40 + include/__iterator/readable_traits.h | 86 + include/__iterator/reverse_access.h | 104 + include/__iterator/reverse_iterator.h | 235 + include/__iterator/size.h | 53 + include/__iterator/unreachable_sentinel.h | 38 + include/__iterator/wrap_iter.h | 285 + include/__libcpp_version | 2 +- include/__locale | 367 +- include/__mbstate_t.h | 44 + include/__memory/addressof.h | 76 + include/__memory/allocation_guard.h | 83 + include/__memory/allocator.h | 249 + include/__memory/allocator_arg_t.h | 78 + include/__memory/allocator_traits.h | 405 + include/__memory/auto_ptr.h | 81 + include/__memory/compressed_pair.h | 185 + include/__memory/concepts.h | 68 + include/__memory/construct_at.h | 110 + include/__memory/pointer_traits.h | 219 + include/__memory/ranges_construct_at.h | 124 + .../ranges_uninitialized_algorithms.h | 318 + include/__memory/raw_storage_iterator.h | 68 + include/__memory/shared_ptr.h | 1719 +++ include/__memory/temporary_buffer.h | 84 + include/__memory/uninitialized_algorithms.h | 350 + include/__memory/unique_ptr.h | 768 ++ include/__memory/uses_allocator.h | 60 + include/__memory/voidify.h | 30 + include/__mutex_base | 51 +- include/__node_handle | 55 +- include/__nullptr | 8 +- include/__numeric/accumulate.h | 52 + include/__numeric/adjacent_difference.h | 72 + include/__numeric/exclusive_scan.h | 53 + include/__numeric/gcd_lcm.h | 96 + include/__numeric/inclusive_scan.h | 60 + include/__numeric/inner_product.h | 53 + include/__numeric/iota.h | 32 + include/__numeric/midpoint.h | 85 + include/__numeric/partial_sum.h | 70 + include/__numeric/reduce.h | 47 + include/__numeric/transform_exclusive_scan.h | 49 + include/__numeric/transform_inclusive_scan.h | 58 + include/__numeric/transform_reduce.h | 54 + include/__random/bernoulli_distribution.h | 143 + include/__random/binomial_distribution.h | 225 + include/__random/cauchy_distribution.h | 162 + include/__random/chi_squared_distribution.h | 144 + include/__random/clamp_to_integral.h | 60 + include/__random/default_random_engine.h | 25 + include/__random/discard_block_engine.h | 203 + include/__random/discrete_distribution.h | 260 + include/__random/exponential_distribution.h | 155 + include/__random/extreme_value_distribution.h | 161 + include/__random/fisher_f_distribution.h | 160 + include/__random/gamma_distribution.h | 213 + include/__random/generate_canonical.h | 53 + include/__random/geometric_distribution.h | 141 + include/__random/independent_bits_engine.h | 271 + include/__random/is_seed_sequence.h | 31 + include/__random/knuth_b.h | 26 + include/__random/linear_congruential_engine.h | 398 + include/__random/log2.h | 74 + include/__random/lognormal_distribution.h | 299 + include/__random/mersenne_twister_engine.h | 534 + .../__random/negative_binomial_distribution.h | 176 + include/__random/normal_distribution.h | 208 + .../piecewise_constant_distribution.h | 356 + .../__random/piecewise_linear_distribution.h | 372 + include/__random/poisson_distribution.h | 277 + include/__random/random_device.h | 88 + include/__random/ranlux.h | 31 + include/__random/seed_seq.h | 153 + include/__random/shuffle_order_engine.h | 283 + include/__random/student_t_distribution.h | 153 + include/__random/subtract_with_carry_engine.h | 352 + include/__random/uniform_int_distribution.h | 290 + .../__random/uniform_random_bit_generator.h | 45 + include/__random/uniform_real_distribution.h | 160 + include/__random/weibull_distribution.h | 155 + include/__ranges/access.h | 227 + include/__ranges/all.h | 82 + include/__ranges/common_view.h | 135 + include/__ranges/concepts.h | 142 + include/__ranges/copyable_box.h | 178 + include/__ranges/counted.h | 81 + include/__ranges/dangling.h | 42 + include/__ranges/data.h | 106 + include/__ranges/drop_view.h | 127 + include/__ranges/empty.h | 82 + include/__ranges/empty_view.h | 45 + include/__ranges/enable_borrowed_range.h | 40 + include/__ranges/enable_view.h | 47 + include/__ranges/iota_view.h | 408 + include/__ranges/join_view.h | 350 + include/__ranges/non_propagating_cache.h | 114 + include/__ranges/owning_view.h | 81 + include/__ranges/range_adaptor.h | 73 + include/__ranges/ref_view.h | 86 + include/__ranges/reverse_view.h | 190 + include/__ranges/single_view.h | 81 + include/__ranges/size.h | 135 + include/__ranges/subrange.h | 289 + include/__ranges/take_view.h | 185 + include/__ranges/transform_view.h | 440 + include/__ranges/view_interface.h | 195 + include/__ranges/views.h | 35 + include/__split_buffer | 82 +- include/__sso_allocator | 76 - include/__std_stream | 6 +- include/__string | 456 +- .../android/locale_bionic.h | 8 +- include/__support/fuchsia/xlocale.h | 22 + include/__support/ibm/gettod_zos.h | 53 + include/{support => __support}/ibm/limits.h | 2 +- include/__support/ibm/locale_mgmt_zos.h | 53 + include/__support/ibm/nanosleep.h | 55 + include/{support => __support}/ibm/support.h | 2 +- include/__support/ibm/xlocale.h | 133 + include/__support/musl/xlocale.h | 57 + include/__support/newlib/xlocale.h | 27 + include/__support/openbsd/xlocale.h | 39 + .../solaris/floatingpoint.h | 0 .../{support => __support}/solaris/wchar.h | 2 +- .../{support => __support}/solaris/xlocale.h | 0 .../win32/limits_msvc_win32.h | 6 +- include/__support/win32/locale_win32.h | 283 + .../xlocale/__nop_locale_mgmt.h | 2 +- .../xlocale/__posix_l_fallback.h | 2 +- .../xlocale/__strtonum_fallback.h | 2 +- include/__thread/poll_with_backoff.h | 69 + include/__thread/timed_backoff_policy.h | 45 + include/__threading_support | 260 +- include/__tree | 263 +- include/__tuple | 48 +- include/__undef_macros | 2 +- include/__utility/as_const.h | 33 + include/__utility/auto_cast.h | 22 + include/__utility/cmp.h | 110 + include/__utility/declval.h | 34 + include/__utility/exchange.h | 37 + include/__utility/forward.h | 37 + include/__utility/in_place.h | 58 + include/__utility/integer_sequence.h | 78 + include/__utility/move.h | 47 + include/__utility/pair.h | 609 + include/__utility/piecewise_construct.h | 29 + include/__utility/priority_tag.h | 26 + include/__utility/rel_ops.h | 62 + include/__utility/swap.h | 50 + include/__utility/to_underlying.h | 40 + include/__utility/transaction.h | 91 + include/__variant/monostate.h | 60 + include/algorithm | 5335 +------- include/any | 41 +- include/array | 270 +- include/atomic | 1255 +- include/barrier | 330 + include/bit | 256 +- include/bitset | 45 +- include/cassert | 2 +- include/ccomplex | 4 +- include/cctype | 32 +- include/cerrno | 4 +- include/cfenv | 30 +- include/cfloat | 4 +- include/charconv | 219 +- include/chrono | 2297 +--- include/cinttypes | 18 +- include/ciso646 | 4 +- include/climits | 4 +- include/clocale | 12 +- include/cmath | 441 +- include/codecvt | 107 +- include/compare | 752 +- include/complex | 51 +- include/complex.h | 6 +- include/concepts | 161 + include/condition_variable | 5 +- include/coroutine | 52 + include/csetjmp | 8 +- include/csignal | 10 +- include/cstdarg | 6 +- include/cstdbool | 4 +- include/cstddef | 77 +- include/cstdint | 60 +- include/cstdio | 112 +- include/cstdlib | 104 +- include/cstring | 52 +- include/ctgmath | 4 +- include/ctime | 58 +- include/ctype.h | 4 +- include/cwchar | 140 +- include/cwctype | 48 +- include/deque | 268 +- include/errno.h | 8 +- include/exception | 22 +- include/execution | 7 +- include/experimental/__config | 10 +- include/experimental/__memory | 33 +- include/experimental/algorithm | 15 +- include/experimental/coroutine | 16 +- include/experimental/deque | 4 +- include/experimental/filesystem | 2 +- include/experimental/forward_list | 4 +- include/experimental/functional | 131 +- include/experimental/iterator | 26 +- include/experimental/list | 4 +- include/experimental/map | 4 +- include/experimental/memory_resource | 29 +- include/experimental/propagate_const | 14 +- include/experimental/regex | 10 +- include/experimental/set | 4 +- include/experimental/simd | 43 +- include/experimental/string | 6 +- include/experimental/type_traits | 10 +- include/experimental/unordered_map | 4 +- include/experimental/unordered_set | 4 +- include/experimental/utility | 2 +- include/experimental/vector | 4 +- include/ext/__hash | 9 +- include/ext/hash_map | 23 +- include/ext/hash_set | 14 +- include/fenv.h | 2 +- include/filesystem | 2443 +--- include/float.h | 6 +- include/format | 564 + include/forward_list | 148 +- include/fstream | 227 +- include/functional | 2725 +--- include/future | 321 +- include/initializer_list | 8 +- include/inttypes.h | 4 +- include/iomanip | 26 +- include/ios | 117 +- include/iosfwd | 87 +- include/iostream | 22 +- include/istream | 135 +- include/iterator | 1843 +-- include/latch | 113 + include/limits | 8 +- include/limits.h | 4 +- include/list | 532 +- include/locale | 571 +- include/locale.h | 10 +- include/map | 267 +- include/math.h | 413 +- include/memory | 4924 +------ include/module.modulemap | 512 +- include/mutex | 56 +- include/new | 234 +- include/numbers | 133 + include/numeric | 512 +- include/optional | 471 +- include/ostream | 167 +- include/queue | 350 +- include/random | 5242 +------- include/ranges | 237 + include/ratio | 35 +- include/regex | 401 +- include/scoped_allocator | 19 +- include/semaphore | 188 + include/set | 189 +- include/setjmp.h | 4 +- include/shared_mutex | 9 +- include/span | 441 +- include/sstream | 481 +- include/stack | 82 +- include/stdbool.h | 4 +- include/stddef.h | 12 +- include/stdexcept | 17 +- include/stdint.h | 4 +- include/stdio.h | 4 +- include/stdlib.h | 76 +- include/streambuf | 26 +- include/string | 1688 +-- include/string.h | 4 +- include/string_view | 269 +- include/strstream | 43 +- include/support/fuchsia/xlocale.h | 22 - include/support/ibm/locale_mgmt_aix.h | 84 - include/support/ibm/xlocale.h | 270 - include/support/musl/xlocale.h | 57 - include/support/newlib/xlocale.h | 27 - include/support/win32/locale_win32.h | 198 - include/system_error | 39 +- include/tgmath.h | 6 +- include/thread | 105 +- include/tuple | 1308 +- include/type_traits | 2089 +-- include/typeindex | 9 +- include/typeinfo | 96 +- include/unordered_map | 668 +- include/unordered_set | 471 +- include/utility | 1487 +-- include/valarray | 433 +- include/variant | 287 +- include/vector | 846 +- include/version | 262 +- include/wchar.h | 15 +- include/wctype.h | 24 +- lib/abi/3.9/x86_64-apple-darwin16.abilist | 2448 ---- lib/abi/3.9/x86_64-linux-gnu.abilist | 2010 --- lib/abi/4.0/x86_64-apple-darwin16.abilist | 2376 ---- lib/abi/4.0/x86_64-unknown-linux-gnu.abilist | 1905 --- lib/abi/5.0/x86_64-apple-darwin16.abilist | 2378 ---- lib/abi/5.0/x86_64-unknown-linux-gnu.abilist | 1883 --- lib/abi/6.0/x86_64-apple-darwin16.abilist | 2378 ---- lib/abi/6.0/x86_64-unknown-linux-gnu.abilist | 1883 --- lib/abi/8.0/x86_64-apple-darwin.v1.abilist | 2360 ---- lib/abi/8.0/x86_64-apple-darwin.v2.abilist | 2315 ---- .../8.0/x86_64-unknown-linux-gnu.v1.abilist | 1861 --- lib/abi/CHANGELOG.TXT | 445 +- lib/abi/CMakeLists.txt | 98 +- lib/abi/README.TXT | 11 +- ...stable.exceptions.no_new_in_libcxx.abilist | 2550 ++++ ...stable.exceptions.no_new_in_libcxx.abilist | 2580 ++++ lib/abi/x86_64-apple-darwin.v1.abilist | 2422 ---- lib/abi/x86_64-apple-darwin.v2.abilist | 2378 ---- ...stable.exceptions.no_new_in_libcxx.abilist | 2044 +++ lib/abi/x86_64-unknown-linux-gnu.v1.abilist | 1919 --- lib/libc++abi-new-delete.exp | 20 - lib/libc++abi.v1.exp | 10 - lib/libc++abi.v2.exp | 10 - lib/libc++sjlj-abi.v1.exp | 160 - lib/libc++sjlj-abi.v2.exp | 310 - src/CMakeLists.txt | 195 +- src/algorithm.cpp | 54 +- src/any.cpp | 8 +- src/atomic.cpp | 194 + src/barrier.cpp | 97 + src/bind.cpp | 2 +- src/charconv.cpp | 90 +- src/chrono.cpp | 272 +- src/chrono_system_time_init.h | 2 + src/condition_variable.cpp | 12 +- src/condition_variable_destructor.cpp | 2 +- src/debug.cpp | 6 +- src/dso_handle.c | 2 - src/exception.cpp | 2 +- src/experimental/memory_resource.cpp | 40 +- .../memory_resource_init_helper.h | 2 + src/filesystem/directory_iterator.cpp | 143 +- src/filesystem/filesystem_common.h | 404 +- src/filesystem/operations.cpp | 816 +- src/filesystem/posix_compat.h | 521 + src/format.cpp | 15 + src/functional.cpp | 8 +- src/future.cpp | 12 +- src/hash.cpp | 2 +- src/include/apple_availability.h | 18 +- src/include/atomic_support.h | 4 +- src/include/config_elast.h | 10 +- src/include/refstring.h | 35 +- src/include/ryu/common.h | 107 + src/include/ryu/d2fixed.h | 60 + src/include/ryu/d2fixed_full_table.h | 4451 +++++++ src/include/ryu/d2s.h | 62 + src/include/ryu/d2s_full_table.h | 368 + src/include/ryu/d2s_intrinsics.h | 257 + src/include/ryu/digit_table.h | 68 + src/include/ryu/f2s.h | 55 + src/include/ryu/ryu.h | 148 + src/include/sso_allocator.h | 77 + src/include/to_chars_floating_point.h | 1076 ++ src/ios.cpp | 34 +- src/ios.instantiations.cpp | 46 + src/iostream.cpp | 53 +- src/iostream_init.h | 2 + src/legacy_pointer_safety.cpp | 23 + src/locale.cpp | 827 +- src/memory.cpp | 74 +- src/mutex.cpp | 28 +- src/mutex_destructor.cpp | 5 +- src/new.cpp | 82 +- src/optional.cpp | 11 +- src/random.cpp | 66 +- src/random_shuffle.cpp | 61 + src/regex.cpp | 124 +- src/ryu/README.txt | 11 + src/ryu/d2fixed.cpp | 669 + src/ryu/d2s.cpp | 782 ++ src/ryu/f2s.cpp | 715 + src/shared_mutex.cpp | 4 +- src/stdexcept.cpp | 2 +- src/string.cpp | 76 +- src/strstream.cpp | 2 +- src/support/ibm/mbsnrtowcs.cpp | 95 + src/support/ibm/wcsnrtombs.cpp | 93 + src/support/ibm/xlocale_zos.cpp | 137 + src/support/runtime/exception_fallback.ipp | 54 +- src/support/runtime/exception_glibcxx.ipp | 8 +- src/support/runtime/exception_libcxxabi.ipp | 4 +- src/support/runtime/exception_libcxxrt.ipp | 4 +- src/support/runtime/exception_msvc.ipp | 50 +- .../runtime/exception_pointer_cxxabi.ipp | 12 +- .../runtime/exception_pointer_glibcxx.ipp | 14 +- .../runtime/exception_pointer_msvc.ipp | 24 +- .../exception_pointer_unimplemented.ipp | 12 +- src/support/runtime/new_handler_fallback.ipp | 4 +- src/support/runtime/stdexcept_default.ipp | 32 +- src/support/runtime/stdexcept_vcruntime.ipp | 2 +- src/support/solaris/wcsnrtombs.inc | 1 - src/support/solaris/xlocale.cpp | 4 +- src/support/win32/locale_win32.cpp | 22 +- src/support/win32/support.cpp | 28 +- src/support/win32/thread_win32.cpp | 11 +- src/system_error.cpp | 36 +- src/thread.cpp | 30 +- src/typeinfo.cpp | 8 +- src/utility.cpp | 2 +- src/valarray.cpp | 2 +- src/variant.cpp | 2 +- src/vector.cpp | 23 +- test/CMakeLists.txt | 112 +- test/configs/apple-libc++-shared.cfg.in | 33 + test/configs/cmake-bridge.cfg.in | 34 + test/configs/ibm-libc++-shared.cfg.in | 33 + test/configs/legacy.cfg.in | 64 + test/configs/llvm-libc++-mingw.cfg.in | 32 + .../configs/llvm-libc++-shared-clangcl.cfg.in | 32 + test/configs/llvm-libc++-shared-gcc.cfg.in | 26 + test/configs/llvm-libc++-shared.cfg.in | 27 + .../configs/llvm-libc++-static-clangcl.cfg.in | 32 + test/configs/llvm-libc++-static.cfg.in | 27 + .../random_shuffle.cxx1z.pass.cpp | 8 +- .../random_shuffle.depr_in_cxx14.fail.cpp | 49 - .../random_shuffle.depr_in_cxx14.verify.cpp | 46 + test/libcxx/algorithms/debug_less.pass.cpp | 8 +- test/libcxx/algorithms/half_positive.pass.cpp | 8 +- .../algorithms/nth_element_stability.pass.cpp | 103 + .../partial_sort_stability.pass.cpp | 103 + ...obust_against_copying_comparators.pass.cpp | 190 + .../libcxx/algorithms/sort_stability.pass.cpp | 100 + .../nothrow_forward_iterator.compile.pass.cpp | 39 + .../nothrow_forward_range.compile.pass.cpp | 43 + .../nothrow_input_iterator.compile.pass.cpp | 32 + .../nothrow_input_range.compile.pass.cpp | 34 + .../nothrow_sentinel_for.compile.pass.cpp | 36 + .../atomics/atomics.align/align.pass.cpp | 110 + .../atomics/atomics.align/align.pass.sh.cpp | 94 - .../atomics/atomics.flag/init_bool.pass.cpp | 4 +- .../memory_order.underlying_type.pass.cpp | 2 - .../atomic_fetch_add.verify.cpp | 74 + .../atomic_fetch_add_explicit.verify.cpp | 77 + .../atomic_fetch_sub.verify.cpp | 74 + .../atomic_fetch_sub_explicit.verify.cpp | 77 + test/libcxx/atomics/bit-int.verify.cpp | 28 + .../diagnose_invalid_memory_order.fail.cpp | 129 - .../diagnose_invalid_memory_order.verify.cpp | 128 + .../atomics/libcpp-has-no-threads.fail.cpp | 25 - .../atomics/libcpp-has-no-threads.pass.cpp | 19 - test/libcxx/atomics/version.pass.cpp | 2 - .../associative/map/at.abort.pass.cpp | 2 +- .../associative/map/at.const.abort.pass.cpp | 2 +- .../associative/non_const_comparator.fail.cpp | 49 - ...non_const_comparator.incomplete.verify.cpp | 59 + .../associative/non_const_comparator.pass.cpp | 60 - .../non_const_comparator.verify.cpp | 50 + .../associative/undef_min_max.pass.cpp | 4 +- .../containers/gnu_cxx/hash_map.pass.cpp | 8 +- .../gnu_cxx/hash_map_name_lookup.pass.cpp | 11 +- .../containers/gnu_cxx/hash_set.pass.cpp | 8 +- .../gnu_cxx/hash_set_name_lookup.pass.cpp | 10 +- .../array/array.zero/db_back.pass.cpp | 9 +- .../array/array.zero/db_front.pass.cpp | 9 +- .../array/array.zero/db_indexing.pass.cpp | 9 +- .../sequences/array/triviality.pass.cpp | 54 + .../sequences/deque/incomplete.pass.cpp | 4 +- .../sequences/deque/pop_back_empty.pass.cpp | 12 +- .../deque/spare_block_handling.pass.cpp | 28 +- .../sequences/list/list.cons/db_copy.pass.cpp | 15 +- .../sequences/list/list.cons/db_move.pass.cpp | 37 - .../list/list.modifiers/emplace_db1.pass.cpp | 38 +- .../list.modifiers/erase_iter_db1.pass.cpp | 16 +- .../list.modifiers/erase_iter_db2.pass.cpp | 16 +- .../erase_iter_iter_db1.pass.cpp | 18 +- .../erase_iter_iter_db2.pass.cpp | 17 +- .../erase_iter_iter_db3.pass.cpp | 17 +- .../erase_iter_iter_db4.pass.cpp | 17 +- .../insert_iter_iter_iter_db1.pass.cpp | 19 +- .../insert_iter_rvalue_db1.pass.cpp | 17 +- .../insert_iter_size_value_db1.pass.cpp | 17 +- .../insert_iter_value_db1.pass.cpp | 18 +- .../list/list.modifiers/pop_back_db1.pass.cpp | 15 +- .../list/list.ops/db_splice_pos_list.pass.cpp | 15 +- .../list.ops/db_splice_pos_list_iter.pass.cpp | 16 +- .../db_splice_pos_list_iter_iter.pass.cpp | 20 +- .../trivial_for_purposes_of_call.pass.cpp | 57 + .../containers/sequences/vector/asan.pass.cpp | 8 +- .../sequences/vector/asan_throw.pass.cpp | 3 +- .../vector/const_value_type.pass.cpp | 2 +- .../sequences/vector/db_back.pass.cpp | 46 +- .../sequences/vector/db_back_2.pass.cpp | 33 + .../sequences/vector/db_cback.pass.cpp | 41 +- .../sequences/vector/db_cback_2.pass.cpp | 30 + .../sequences/vector/db_cfront.pass.cpp | 41 +- .../sequences/vector/db_cfront_2.pass.cpp | 30 + .../sequences/vector/db_cindex.pass.cpp | 36 +- .../sequences/vector/db_cindex_2.pass.cpp | 32 + .../sequences/vector/db_front.pass.cpp | 46 +- .../sequences/vector/db_front_2.pass.cpp | 33 + .../sequences/vector/db_index.pass.cpp | 45 +- .../sequences/vector/db_index_2.pass.cpp | 32 + .../sequences/vector/db_iterators_10.pass.cpp | 31 + .../sequences/vector/db_iterators_11.pass.cpp | 33 + .../sequences/vector/db_iterators_12.pass.cpp | 35 + .../sequences/vector/db_iterators_13.pass.cpp | 34 + .../sequences/vector/db_iterators_14.pass.cpp | 34 + .../sequences/vector/db_iterators_15.pass.cpp | 31 + .../sequences/vector/db_iterators_2.pass.cpp | 44 +- .../sequences/vector/db_iterators_3.pass.cpp | 44 +- .../sequences/vector/db_iterators_4.pass.cpp | 46 +- .../sequences/vector/db_iterators_5.pass.cpp | 52 +- .../sequences/vector/db_iterators_6.pass.cpp | 49 +- .../sequences/vector/db_iterators_7.pass.cpp | 49 +- .../sequences/vector/db_iterators_8.pass.cpp | 44 +- .../sequences/vector/db_iterators_9.pass.cpp | 31 + ...eption_safety_exceptions_disabled.pass.cpp | 56 + ...xception_safety_exceptions_disabled.sh.cpp | 57 - .../sequences/vector/pop_back_empty.pass.cpp | 12 +- .../vector/robust_against_adl.pass.cpp | 47 + .../containers/unord/next_pow2.pass.cpp | 2 +- .../unord/non_const_comparator.fail.cpp | 59 - ...non_const_comparator.incomplete.verify.cpp | 59 + .../unord/non_const_comparator.pass.cpp | 60 - .../unord/non_const_comparator.verify.cpp | 59 + .../unord/unord.map/at.abort.pass.cpp | 4 +- .../unord/unord.map/at.const.abort.pass.cpp | 4 +- .../unord/unord.map/bucket_size.pass.cpp | 33 + .../unord/unord.map/db_bucket.pass.cpp | 29 + .../db_insert_hint_const_lvalue.pass.cpp | 40 + .../unord.map/db_insert_hint_rvalue.pass.cpp | 37 + .../unord/unord.map/db_iterators_10.pass.cpp | 34 + .../unord/unord.map/db_iterators_7.pass.cpp | 44 +- .../unord/unord.map/db_iterators_8.pass.cpp | 41 +- .../unord/unord.map/db_iterators_9.pass.cpp | 37 + .../unord.map/db_local_iterators_10.pass.cpp | 33 + .../unord.map/db_local_iterators_7.pass.cpp | 47 +- .../unord.map/db_local_iterators_8.pass.cpp | 40 +- .../unord.map/db_local_iterators_9.pass.cpp | 38 + .../unord/unord.map/db_swap_1.pass.cpp | 40 + .../unord/unord.map/max_load_factor.pass.cpp | 34 + .../erase_iter_db1.pass.cpp | 31 + .../erase_iter_db2.pass.cpp | 32 + .../erase_iter_iter_db1.pass.cpp | 32 + .../erase_iter_iter_db2.pass.cpp | 32 + .../erase_iter_iter_db3.pass.cpp | 32 + .../erase_iter_iter_db4.pass.cpp | 30 + .../unord/unord.multimap/bucket.pass.cpp | 33 + .../unord/unord.multimap/bucket_size.pass.cpp | 33 + .../db_insert_hint_const_lvalue.pass.cpp | 34 + .../db_insert_hint_rvalue.pass.cpp | 37 + .../unord.multimap/db_iterators_10.pass.cpp | 34 + .../unord.multimap/db_iterators_7.pass.cpp | 34 + .../unord.multimap/db_iterators_8.pass.cpp | 31 + .../unord.multimap/db_iterators_9.pass.cpp | 37 + .../db_local_iterators_10.pass.cpp | 33 + .../db_local_iterators_7.pass.cpp | 36 + .../db_local_iterators_8.pass.cpp | 30 + .../db_local_iterators_9.pass.cpp | 39 + .../unord/unord.multimap/db_swap_1.pass.cpp | 41 + .../unord.multimap/max_load_factor.pass.cpp | 34 + .../erase_iter_db1.pass.cpp | 31 + .../erase_iter_db2.pass.cpp | 32 + .../erase_iter_iter_db1.pass.cpp | 32 + .../erase_iter_iter_db2.pass.cpp | 32 + .../erase_iter_iter_db3.pass.cpp | 32 + .../erase_iter_iter_db4.pass.cpp | 30 + .../unord/unord.multiset/bucket.pass.cpp | 32 + .../unord/unord.multiset/bucket_size.pass.cpp | 32 + .../db_insert_hint_const_lvalue.pass.cpp | 34 + .../unord.multiset/db_iterators_10.pass.cpp | 32 + .../unord.multiset/db_iterators_7.pass.cpp | 35 + .../unord.multiset/db_iterators_8.pass.cpp | 30 + .../unord.multiset/db_iterators_9.pass.cpp | 36 + .../db_local_iterators_10.pass.cpp | 33 + .../db_local_iterators_7.pass.cpp | 37 + .../db_local_iterators_8.pass.cpp | 31 + .../db_local_iterators_9.pass.cpp | 38 + .../unord/unord.multiset/db_swap_1.pass.cpp | 39 + .../unord.multiset/erase_iter_db1.pass.cpp | 30 + .../unord.multiset/erase_iter_db2.pass.cpp | 31 + .../erase_iter_iter_db1.pass.cpp | 31 + .../erase_iter_iter_db2.pass.cpp | 31 + .../erase_iter_iter_db3.pass.cpp | 31 + .../erase_iter_iter_db4.pass.cpp | 29 + .../unord.multiset/max_load_factor.pass.cpp | 33 + .../unord/unord.set/bucket.pass.cpp | 32 + .../unord/unord.set/bucket_size.pass.cpp | 32 + .../db_insert_hint_const_lvalue.pass.cpp | 34 + .../unord/unord.set/db_iterators_10.pass.cpp | 32 + .../unord/unord.set/db_iterators_7.pass.cpp | 35 + .../unord/unord.set/db_iterators_8.pass.cpp | 30 + .../unord/unord.set/db_iterators_9.pass.cpp | 36 + .../unord.set/db_local_iterators_10.pass.cpp | 33 + .../unord.set/db_local_iterators_7.pass.cpp | 37 + .../unord.set/db_local_iterators_8.pass.cpp | 31 + .../unord.set/db_local_iterators_9.pass.cpp | 38 + .../unord/unord.set/db_swap_1.pass.cpp | 39 + .../unord/unord.set/erase_iter_db1.pass.cpp | 30 + .../unord/unord.set/erase_iter_db2.pass.cpp | 31 + .../unord.set/erase_iter_iter_db1.pass.cpp | 31 + .../unord.set/erase_iter_iter_db2.pass.cpp | 31 + .../unord.set/erase_iter_iter_db3.pass.cpp | 31 + .../unord.set/erase_iter_iter_db4.pass.cpp | 29 + .../unord/unord.set/max_load_factor.pass.cpp | 34 + .../missing_hash_specialization.fail.cpp | 4 +- .../containers/views/span.cons/range.pass.cpp | 141 + .../views/span.cons/range.verify.cpp | 118 + .../db_associative_container_tests.pass.cpp | 10 +- ...e_container_iterators.multithread.pass.cpp | 9 +- .../db_sequence_container_iterators.pass.cpp | 44 +- .../debug/containers/db_string.pass.cpp | 15 +- .../db_unord_container_tests.pass.cpp | 9 +- test/libcxx/debug/db_string_view.pass.cpp | 25 +- test/libcxx/debug/debug_abort.pass.cpp | 9 +- test/libcxx/debug/debug_helper_test.pass.cpp | 23 +- test/libcxx/debug/debug_register.pass.cpp | 9 +- test/libcxx/debug/extern-templates.sh.cpp | 54 + .../auto.ptr/auto_ptr.cxx1z.pass.cpp | 8 +- .../auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp | 38 - .../auto_ptr.depr_in_cxx11.verify.cpp | 35 + .../depr/depr.c.headers/extern_c.pass.cpp | 12 +- .../depr/depr.c.headers/locale_h.pass.cpp | 2 + .../depr.c.headers/math_h.compile.pass.cpp | 26 + test/libcxx/depr/depr.c.headers/math_h.sh.cpp | 22 - .../no_fgetpos_fsetpos.verify.cpp | 20 + .../stdint_h.std_types_t.compile.pass.cpp | 263 + .../stdint_h.xopen_source.compile.pass.cpp | 260 + .../allocator.members/address.cxx2a.pass.cpp | 49 + .../address.depr_in_cxx17.verify.cpp | 33 + .../allocator.members/allocate.cxx2a.pass.cpp | 93 + .../allocate.cxx2a.verify.cpp | 34 + .../allocate.depr_in_cxx17.verify.cpp | 29 + .../construct.cxx2a.pass.cpp | 152 + .../allocator.members/max_size.cxx2a.pass.cpp | 37 + .../allocator_types.cxx2a.pass.cpp | 51 + .../typedefs.depr_in_cxx17.verify.cpp | 125 + .../adaptors.depr_in_cxx11.fail.cpp | 58 - .../adaptors.depr_in_cxx11.verify.cpp | 55 + .../depr.adaptors.cxx1z.pass.cpp | 6 +- .../depr/depr.str.strstreams/version.pass.cpp | 2 + .../enable_removed_cpp17_features.pass.cpp | 4 +- .../get_unexpected.pass.cpp | 3 +- .../set_unexpected.pass.cpp | 4 +- .../exception.unexpected/unexpected.pass.cpp | 4 +- .../unexpected_disabled_cpp17.fail.cpp | 2 +- .../algorithm/adjacent_find.module.verify.cpp | 15 + .../algorithm/all_of.module.verify.cpp | 15 + .../algorithm/any_of.module.verify.cpp | 15 + .../algorithm/binary_search.module.verify.cpp | 15 + .../algorithm/clamp.module.verify.cpp | 15 + .../algorithm/comp.module.verify.cpp | 15 + .../algorithm/comp_ref_type.module.verify.cpp | 15 + .../algorithm/copy.module.verify.cpp | 15 + .../algorithm/copy_backward.module.verify.cpp | 15 + .../algorithm/copy_if.module.verify.cpp | 15 + .../algorithm/copy_n.module.verify.cpp | 15 + .../algorithm/count.module.verify.cpp | 15 + .../algorithm/count_if.module.verify.cpp | 15 + .../algorithm/equal.module.verify.cpp | 15 + .../algorithm/equal_range.module.verify.cpp | 15 + .../algorithm/fill.module.verify.cpp | 15 + .../algorithm/fill_n.module.verify.cpp | 15 + .../algorithm/find.module.verify.cpp | 15 + .../algorithm/find_end.module.verify.cpp | 15 + .../algorithm/find_first_of.module.verify.cpp | 15 + .../algorithm/find_if.module.verify.cpp | 15 + .../algorithm/find_if_not.module.verify.cpp | 15 + .../algorithm/for_each.module.verify.cpp | 15 + .../algorithm/for_each_n.module.verify.cpp | 15 + .../algorithm/generate.module.verify.cpp | 15 + .../algorithm/generate_n.module.verify.cpp | 15 + .../algorithm/half_positive.module.verify.cpp | 15 + .../in_in_out_result.module.verify.cpp | 15 + .../algorithm/in_in_result.module.verify.cpp | 15 + .../algorithm/in_out_result.module.verify.cpp | 15 + .../algorithm/includes.module.verify.cpp | 15 + .../algorithm/inplace_merge.module.verify.cpp | 15 + .../algorithm/is_heap.module.verify.cpp | 15 + .../algorithm/is_heap_until.module.verify.cpp | 15 + .../is_partitioned.module.verify.cpp | 15 + .../is_permutation.module.verify.cpp | 15 + .../algorithm/is_sorted.module.verify.cpp | 15 + .../is_sorted_until.module.verify.cpp | 15 + .../algorithm/iter_swap.module.verify.cpp | 15 + .../lexicographical_compare.module.verify.cpp | 15 + .../algorithm/lower_bound.module.verify.cpp | 15 + .../algorithm/make_heap.module.verify.cpp | 15 + .../algorithm/max.module.verify.cpp | 15 + .../algorithm/max_element.module.verify.cpp | 15 + .../algorithm/merge.module.verify.cpp | 15 + .../algorithm/min.module.verify.cpp | 15 + .../algorithm/min_element.module.verify.cpp | 15 + .../algorithm/minmax.module.verify.cpp | 15 + .../minmax_element.module.verify.cpp | 15 + .../algorithm/mismatch.module.verify.cpp | 15 + .../algorithm/move.module.verify.cpp | 15 + .../algorithm/move_backward.module.verify.cpp | 15 + .../next_permutation.module.verify.cpp | 15 + .../algorithm/none_of.module.verify.cpp | 15 + .../algorithm/nth_element.module.verify.cpp | 15 + .../algorithm/partial_sort.module.verify.cpp | 15 + .../partial_sort_copy.module.verify.cpp | 15 + .../algorithm/partition.module.verify.cpp | 15 + .../partition_copy.module.verify.cpp | 15 + .../partition_point.module.verify.cpp | 15 + .../algorithm/pop_heap.module.verify.cpp | 15 + .../prev_permutation.module.verify.cpp | 15 + .../algorithm/push_heap.module.verify.cpp | 15 + .../algorithm/remove.module.verify.cpp | 15 + .../algorithm/remove_copy.module.verify.cpp | 15 + .../remove_copy_if.module.verify.cpp | 15 + .../algorithm/remove_if.module.verify.cpp | 15 + .../algorithm/replace.module.verify.cpp | 15 + .../algorithm/replace_copy.module.verify.cpp | 15 + .../replace_copy_if.module.verify.cpp | 15 + .../algorithm/replace_if.module.verify.cpp | 15 + .../algorithm/reverse.module.verify.cpp | 15 + .../algorithm/reverse_copy.module.verify.cpp | 15 + .../algorithm/rotate.module.verify.cpp | 15 + .../algorithm/rotate_copy.module.verify.cpp | 15 + .../algorithm/sample.module.verify.cpp | 15 + .../algorithm/search.module.verify.cpp | 15 + .../algorithm/search_n.module.verify.cpp | 15 + .../set_difference.module.verify.cpp | 15 + .../set_intersection.module.verify.cpp | 15 + ...set_symmetric_difference.module.verify.cpp | 15 + .../algorithm/set_union.module.verify.cpp | 15 + .../algorithm/shift_left.module.verify.cpp | 15 + .../algorithm/shift_right.module.verify.cpp | 15 + .../algorithm/shuffle.module.verify.cpp | 15 + .../algorithm/sift_down.module.verify.cpp | 15 + .../algorithm/sort.module.verify.cpp | 15 + .../algorithm/sort_heap.module.verify.cpp | 15 + .../stable_partition.module.verify.cpp | 15 + .../algorithm/stable_sort.module.verify.cpp | 15 + .../algorithm/swap_ranges.module.verify.cpp | 15 + .../algorithm/transform.module.verify.cpp | 15 + .../algorithm/unique.module.verify.cpp | 15 + .../algorithm/unique_copy.module.verify.cpp | 15 + .../algorithm/unwrap_iter.module.verify.cpp | 15 + .../algorithm/upper_bound.module.verify.cpp | 15 + .../availability.module.verify.cpp | 15 + .../bit/bit_cast.module.verify.cpp | 15 + .../bit/byteswap.module.verify.cpp | 15 + .../bit_reference.module.verify.cpp | 15 + .../detail.headers/bits.module.verify.cpp | 15 + .../charconv/chars_format.module.verify.cpp | 15 + .../from_chars_result.module.verify.cpp | 15 + .../to_chars_result.module.verify.cpp | 15 + .../chrono/calendar.module.verify.cpp | 15 + .../convert_to_timespec.module.verify.cpp | 15 + .../chrono/duration.module.verify.cpp | 15 + .../chrono/file_clock.module.verify.cpp | 15 + .../high_resolution_clock.module.verify.cpp | 15 + .../chrono/steady_clock.module.verify.cpp | 15 + .../chrono/system_clock.module.verify.cpp | 15 + .../chrono/time_point.module.verify.cpp | 15 + ...mmon_comparison_category.module.verify.cpp | 15 + ...e_partial_order_fallback.module.verify.cpp | 15 + ...re_strong_order_fallback.module.verify.cpp | 15 + .../compare_three_way.module.verify.cpp | 15 + ...compare_three_way_result.module.verify.cpp | 15 + ...pare_weak_order_fallback.module.verify.cpp | 15 + .../compare/is_eq.module.verify.cpp | 15 + .../compare/ordering.module.verify.cpp | 15 + .../compare/partial_order.module.verify.cpp | 15 + .../compare/strong_order.module.verify.cpp | 15 + .../compare/synth_three_way.module.verify.cpp | 15 + .../three_way_comparable.module.verify.cpp | 15 + .../compare/weak_order.module.verify.cpp | 15 + .../concepts/arithmetic.module.verify.cpp | 15 + .../concepts/assignable.module.verify.cpp | 15 + .../boolean_testable.module.verify.cpp | 15 + .../concepts/class_or_enum.module.verify.cpp | 15 + .../common_reference_with.module.verify.cpp | 15 + .../concepts/common_with.module.verify.cpp | 15 + .../concepts/constructible.module.verify.cpp | 15 + .../concepts/convertible_to.module.verify.cpp | 15 + .../concepts/copyable.module.verify.cpp | 15 + .../concepts/derived_from.module.verify.cpp | 15 + .../concepts/destructible.module.verify.cpp | 15 + .../concepts/different_from.module.verify.cpp | 15 + .../equality_comparable.module.verify.cpp | 15 + .../concepts/invocable.module.verify.cpp | 15 + .../concepts/movable.module.verify.cpp | 15 + .../concepts/predicate.module.verify.cpp | 15 + .../concepts/regular.module.verify.cpp | 15 + .../concepts/relation.module.verify.cpp | 15 + .../concepts/same_as.module.verify.cpp | 15 + .../concepts/semiregular.module.verify.cpp | 15 + .../concepts/swappable.module.verify.cpp | 15 + .../totally_ordered.module.verify.cpp | 15 + .../coroutine_handle.module.verify.cpp | 15 + .../coroutine_traits.module.verify.cpp | 15 + .../noop_coroutine_handle.module.verify.cpp | 15 + .../trivial_awaitables.module.verify.cpp | 15 + .../detail.headers/errc.module.verify.cpp | 15 + .../filesystem/copy_options.module.verify.cpp | 15 + .../directory_entry.module.verify.cpp | 15 + .../directory_iterator.module.verify.cpp | 15 + .../directory_options.module.verify.cpp | 15 + .../filesystem/file_status.module.verify.cpp | 15 + .../file_time_type.module.verify.cpp | 15 + .../filesystem/file_type.module.verify.cpp | 15 + .../filesystem_error.module.verify.cpp | 15 + .../filesystem/operations.module.verify.cpp | 15 + .../filesystem/path.module.verify.cpp | 15 + .../path_iterator.module.verify.cpp | 15 + .../filesystem/perm_options.module.verify.cpp | 15 + .../filesystem/perms.module.verify.cpp | 15 + ...rsive_directory_iterator.module.verify.cpp | 15 + .../filesystem/space_info.module.verify.cpp | 15 + .../filesystem/u8path.module.verify.cpp | 15 + .../format/format_arg.module.verify.cpp | 15 + .../format/format_args.module.verify.cpp | 15 + .../format/format_context.module.verify.cpp | 15 + .../format/format_error.module.verify.cpp | 15 + .../format/format_fwd.module.verify.cpp | 15 + .../format_parse_context.module.verify.cpp | 15 + .../format/format_string.module.verify.cpp | 15 + .../format_to_n_result.module.verify.cpp | 15 + .../format/formatter.module.verify.cpp | 15 + .../format/formatter_bool.module.verify.cpp | 15 + .../format/formatter_char.module.verify.cpp | 15 + ...formatter_floating_point.module.verify.cpp | 15 + .../formatter_integer.module.verify.cpp | 15 + .../formatter_integral.module.verify.cpp | 15 + .../formatter_pointer.module.verify.cpp | 15 + .../format/formatter_string.module.verify.cpp | 15 + .../parser_std_format_spec.module.verify.cpp | 15 + .../binary_function.module.verify.cpp | 15 + .../binary_negate.module.verify.cpp | 15 + .../functional/bind.module.verify.cpp | 15 + .../functional/bind_back.module.verify.cpp | 15 + .../functional/bind_front.module.verify.cpp | 15 + .../functional/binder1st.module.verify.cpp | 15 + .../functional/binder2nd.module.verify.cpp | 15 + .../functional/compose.module.verify.cpp | 15 + .../default_searcher.module.verify.cpp | 15 + .../functional/function.module.verify.cpp | 15 + .../functional/hash.module.verify.cpp | 15 + .../functional/identity.module.verify.cpp | 15 + .../functional/invoke.module.verify.cpp | 15 + .../is_transparent.module.verify.cpp | 15 + .../functional/mem_fn.module.verify.cpp | 15 + .../functional/mem_fun_ref.module.verify.cpp | 15 + .../functional/not_fn.module.verify.cpp | 15 + .../functional/operations.module.verify.cpp | 15 + .../perfect_forward.module.verify.cpp | 15 + ...inter_to_binary_function.module.verify.cpp | 15 + ...ointer_to_unary_function.module.verify.cpp | 15 + .../ranges_operations.module.verify.cpp | 15 + .../reference_wrapper.module.verify.cpp | 15 + .../unary_function.module.verify.cpp | 15 + .../functional/unary_negate.module.verify.cpp | 15 + .../functional/unwrap_ref.module.verify.cpp | 15 + .../weak_result_type.module.verify.cpp | 15 + .../iterator/access.module.verify.cpp | 15 + .../iterator/advance.module.verify.cpp | 15 + .../back_insert_iterator.module.verify.cpp | 15 + .../common_iterator.module.verify.cpp | 15 + .../iterator/concepts.module.verify.cpp | 15 + .../counted_iterator.module.verify.cpp | 15 + .../iterator/data.module.verify.cpp | 15 + .../default_sentinel.module.verify.cpp | 15 + .../iterator/distance.module.verify.cpp | 15 + .../iterator/empty.module.verify.cpp | 15 + .../erase_if_container.module.verify.cpp | 15 + .../front_insert_iterator.module.verify.cpp | 15 + .../incrementable_traits.module.verify.cpp | 15 + .../indirectly_comparable.module.verify.cpp | 15 + .../insert_iterator.module.verify.cpp | 15 + .../istream_iterator.module.verify.cpp | 15 + .../istreambuf_iterator.module.verify.cpp | 15 + .../iterator/iter_move.module.verify.cpp | 15 + .../iterator/iter_swap.module.verify.cpp | 15 + .../iterator/iterator.module.verify.cpp | 15 + .../iterator_traits.module.verify.cpp | 15 + .../iterator/move_iterator.module.verify.cpp | 15 + .../iterator/next.module.verify.cpp | 15 + .../ostream_iterator.module.verify.cpp | 15 + .../ostreambuf_iterator.module.verify.cpp | 15 + .../iterator/prev.module.verify.cpp | 15 + .../iterator/projected.module.verify.cpp | 15 + .../readable_traits.module.verify.cpp | 15 + .../iterator/reverse_access.module.verify.cpp | 15 + .../reverse_iterator.module.verify.cpp | 15 + .../iterator/size.module.verify.cpp | 15 + .../unreachable_sentinel.module.verify.cpp | 15 + .../iterator/wrap_iter.module.verify.cpp | 15 + .../detail.headers/locale.module.verify.cpp | 15 + .../mbstate_t.h.module.verify.cpp | 15 + .../memory/addressof.module.verify.cpp | 15 + .../memory/allocation_guard.module.verify.cpp | 15 + .../memory/allocator.module.verify.cpp | 15 + .../memory/allocator_arg_t.module.verify.cpp | 15 + .../memory/allocator_traits.module.verify.cpp | 15 + .../memory/auto_ptr.module.verify.cpp | 15 + .../memory/compressed_pair.module.verify.cpp | 15 + .../memory/concepts.module.verify.cpp | 15 + .../memory/construct_at.module.verify.cpp | 15 + .../memory/pointer_traits.module.verify.cpp | 15 + .../ranges_construct_at.module.verify.cpp | 15 + ...uninitialized_algorithms.module.verify.cpp | 15 + .../raw_storage_iterator.module.verify.cpp | 15 + .../memory/shared_ptr.module.verify.cpp | 15 + .../memory/temporary_buffer.module.verify.cpp | 15 + ...uninitialized_algorithms.module.verify.cpp | 15 + .../memory/unique_ptr.module.verify.cpp | 15 + .../memory/uses_allocator.module.verify.cpp | 15 + .../memory/voidify.module.verify.cpp | 15 + .../mutex_base.module.verify.cpp | 15 + .../node_handle.module.verify.cpp | 15 + .../numeric/accumulate.module.verify.cpp | 15 + .../adjacent_difference.module.verify.cpp | 15 + .../numeric/exclusive_scan.module.verify.cpp | 15 + .../numeric/gcd_lcm.module.verify.cpp | 15 + .../numeric/inclusive_scan.module.verify.cpp | 15 + .../numeric/inner_product.module.verify.cpp | 15 + .../numeric/iota.module.verify.cpp | 15 + .../numeric/midpoint.module.verify.cpp | 15 + .../numeric/partial_sum.module.verify.cpp | 15 + .../numeric/reduce.module.verify.cpp | 15 + ...transform_exclusive_scan.module.verify.cpp | 15 + ...transform_inclusive_scan.module.verify.cpp | 15 + .../transform_reduce.module.verify.cpp | 15 + .../bernoulli_distribution.module.verify.cpp | 15 + .../binomial_distribution.module.verify.cpp | 15 + .../cauchy_distribution.module.verify.cpp | 15 + ...chi_squared_distribution.module.verify.cpp | 15 + .../clamp_to_integral.module.verify.cpp | 15 + .../default_random_engine.module.verify.cpp | 15 + .../discard_block_engine.module.verify.cpp | 15 + .../discrete_distribution.module.verify.cpp | 15 + ...exponential_distribution.module.verify.cpp | 15 + ...treme_value_distribution.module.verify.cpp | 15 + .../fisher_f_distribution.module.verify.cpp | 15 + .../gamma_distribution.module.verify.cpp | 15 + .../generate_canonical.module.verify.cpp | 15 + .../geometric_distribution.module.verify.cpp | 15 + .../independent_bits_engine.module.verify.cpp | 15 + .../random/is_seed_sequence.module.verify.cpp | 15 + .../random/knuth_b.module.verify.cpp | 15 + ...near_congruential_engine.module.verify.cpp | 15 + .../random/log2.module.verify.cpp | 15 + .../lognormal_distribution.module.verify.cpp | 15 + .../mersenne_twister_engine.module.verify.cpp | 15 + ...ve_binomial_distribution.module.verify.cpp | 15 + .../normal_distribution.module.verify.cpp | 15 + ...se_constant_distribution.module.verify.cpp | 15 + ...wise_linear_distribution.module.verify.cpp | 15 + .../poisson_distribution.module.verify.cpp | 15 + .../random/random_device.module.verify.cpp | 15 + .../random/ranlux.module.verify.cpp | 15 + .../random/seed_seq.module.verify.cpp | 15 + .../shuffle_order_engine.module.verify.cpp | 15 + .../student_t_distribution.module.verify.cpp | 15 + ...btract_with_carry_engine.module.verify.cpp | 15 + ...uniform_int_distribution.module.verify.cpp | 15 + ...orm_random_bit_generator.module.verify.cpp | 15 + ...niform_real_distribution.module.verify.cpp | 15 + .../weibull_distribution.module.verify.cpp | 15 + .../ranges/access.module.verify.cpp | 15 + .../ranges/all.module.verify.cpp | 15 + .../ranges/common_view.module.verify.cpp | 15 + .../ranges/concepts.module.verify.cpp | 15 + .../ranges/copyable_box.module.verify.cpp | 15 + .../ranges/counted.module.verify.cpp | 15 + .../ranges/dangling.module.verify.cpp | 15 + .../ranges/data.module.verify.cpp | 15 + .../ranges/drop_view.module.verify.cpp | 15 + .../ranges/empty.module.verify.cpp | 15 + .../ranges/empty_view.module.verify.cpp | 15 + .../enable_borrowed_range.module.verify.cpp | 15 + .../ranges/enable_view.module.verify.cpp | 15 + .../ranges/iota_view.module.verify.cpp | 15 + .../ranges/join_view.module.verify.cpp | 15 + .../non_propagating_cache.module.verify.cpp | 15 + .../ranges/owning_view.module.verify.cpp | 15 + .../ranges/range_adaptor.module.verify.cpp | 15 + .../ranges/ref_view.module.verify.cpp | 15 + .../ranges/reverse_view.module.verify.cpp | 15 + .../ranges/single_view.module.verify.cpp | 15 + .../ranges/size.module.verify.cpp | 15 + .../ranges/subrange.module.verify.cpp | 15 + .../ranges/take_view.module.verify.cpp | 15 + .../ranges/transform_view.module.verify.cpp | 15 + .../ranges/view_interface.module.verify.cpp | 15 + .../ranges/views.module.verify.cpp | 15 + .../split_buffer.module.verify.cpp | 15 + .../std_stream.module.verify.cpp | 15 + .../detail.headers/string.module.verify.cpp | 15 + .../poll_with_backoff.module.verify.cpp | 15 + .../timed_backoff_policy.module.verify.cpp | 15 + .../detail.headers/tuple.module.verify.cpp | 15 + .../utility/as_const.module.verify.cpp | 15 + .../utility/auto_cast.module.verify.cpp | 15 + .../utility/cmp.module.verify.cpp | 15 + .../utility/declval.module.verify.cpp | 15 + .../utility/exchange.module.verify.cpp | 15 + .../utility/forward.module.verify.cpp | 15 + .../utility/in_place.module.verify.cpp | 15 + .../integer_sequence.module.verify.cpp | 15 + .../utility/move.module.verify.cpp | 15 + .../utility/pair.module.verify.cpp | 15 + .../piecewise_construct.module.verify.cpp | 15 + .../utility/priority_tag.module.verify.cpp | 15 + .../utility/rel_ops.module.verify.cpp | 15 + .../utility/swap.module.verify.cpp | 15 + .../utility/to_underlying.module.verify.cpp | 15 + .../utility/transaction.module.verify.cpp | 15 + .../variant/monostate.module.verify.cpp | 15 + .../diagnostics/enable_nodiscard.fail.cpp | 34 - .../diagnostics/enable_nodiscard.verify.cpp | 29 + ...ble_nodiscard_disable_after_cxx17.fail.cpp | 34 - ...e_nodiscard_disable_after_cxx17.verify.cpp | 28 + ...e_nodiscard_disable_nodiscard_ext.fail.cpp | 32 - ...nodiscard_disable_nodiscard_ext.verify.cpp | 25 + .../diagnostics/errno/version_cerrno.pass.cpp | 1 - test/libcxx/diagnostics/nodiscard.pass.cpp | 1 - .../diagnostics/nodiscard_aftercxx17.fail.cpp | 24 - .../diagnostics/nodiscard_aftercxx17.pass.cpp | 5 +- .../nodiscard_aftercxx17.verify.cpp | 23 + .../diagnostics/nodiscard_extensions.fail.cpp | 300 - .../diagnostics/nodiscard_extensions.pass.cpp | 59 +- .../nodiscard_extensions.verify.cpp | 352 + test/libcxx/double_include.sh.cpp | 180 +- .../filesystem/deprecated.fail.cpp | 20 - .../filesystem/deprecated.verify.cpp | 20 + .../experimental/filesystem/version.pass.cpp | 2 + .../dialect_support.pass.cpp | 59 + .../support.coroutines/dialect_support.sh.cpp | 60 - .../support.coroutines/version.pass.cpp | 23 + .../support.coroutines/version.sh.cpp | 26 - .../construct_piecewise_pair.pass.cpp | 2 +- .../db_deallocate.pass.cpp | 2 +- .../db_deallocate.pass.cpp | 2 +- .../header_deque_libcpp_version.pass.cpp | 2 +- ...eader_forward_list_libcpp_version.pass.cpp | 2 +- .../header_list_libcpp_version.pass.cpp | 2 +- .../header_map_libcpp_version.pass.cpp | 2 +- .../header_regex_libcpp_version.pass.cpp | 3 +- .../header_set_libcpp_version.pass.cpp | 2 +- .../header_string_libcpp_version.pass.cpp | 2 +- ...ader_unordered_map_libcpp_version.pass.cpp | 2 +- ...ader_unordered_set_libcpp_version.pass.cpp | 2 +- .../header_vector_libcpp_version.pass.cpp | 2 +- .../global_memory_resource_lifetime.pass.cpp | 2 +- .../new_delete_resource_lifetime.pass.cpp | 2 +- .../memory.resource.synop/version.pass.cpp | 2 +- ...l.cpp => specializations.compile.fail.cpp} | 0 ...il.cpp => const_iterator.compile.fail.cpp} | 0 test/libcxx/extensions/nothing_to_do.pass.cpp | 13 - test/libcxx/fuzzing/fuzz.h | 144 + test/libcxx/fuzzing/make_heap.pass.cpp | 27 + test/libcxx/fuzzing/nth_element.cpp | 37 - test/libcxx/fuzzing/nth_element.pass.cpp | 42 + test/libcxx/fuzzing/partial_sort.cpp | 37 - test/libcxx/fuzzing/partial_sort.pass.cpp | 40 + test/libcxx/fuzzing/partial_sort_copy.cpp | 37 - .../libcxx/fuzzing/partial_sort_copy.pass.cpp | 41 + test/libcxx/fuzzing/partition.cpp | 37 - test/libcxx/fuzzing/partition.pass.cpp | 30 + test/libcxx/fuzzing/partition_copy.cpp | 37 - test/libcxx/fuzzing/partition_copy.pass.cpp | 65 + test/libcxx/fuzzing/pop_heap.pass.cpp | 33 + test/libcxx/fuzzing/push_heap.pass.cpp | 40 + test/libcxx/fuzzing/random.pass.cpp | 195 + test/libcxx/fuzzing/regex.pass.cpp | 46 + test/libcxx/fuzzing/regex_ECMAScript.cpp | 36 - test/libcxx/fuzzing/regex_POSIX.cpp | 36 - test/libcxx/fuzzing/regex_awk.cpp | 36 - test/libcxx/fuzzing/regex_egrep.cpp | 36 - test/libcxx/fuzzing/regex_extended.cpp | 36 - test/libcxx/fuzzing/regex_grep.cpp | 36 - test/libcxx/fuzzing/search.pass.cpp | 35 + test/libcxx/fuzzing/sort.cpp | 37 - test/libcxx/fuzzing/sort.pass.cpp | 27 + test/libcxx/fuzzing/stable_partition.cpp | 37 - test/libcxx/fuzzing/stable_partition.pass.cpp | 38 + test/libcxx/fuzzing/stable_sort.cpp | 37 - test/libcxx/fuzzing/stable_sort.pass.cpp | 39 + test/libcxx/fuzzing/unique.cpp | 37 - test/libcxx/fuzzing/unique.pass.cpp | 54 + test/libcxx/fuzzing/unique_copy.cpp | 37 - test/libcxx/fuzzing/unique_copy.pass.cpp | 56 + .../gdb}/gdb_pretty_printer_test.py | 22 +- .../gdb}/gdb_pretty_printer_test.sh.cpp | 106 +- test/libcxx/include_as_c.sh.cpp | 28 +- .../algorithm.inclusions.compile.pass.cpp | 26 + .../array.inclusions.compile.pass.cpp | 29 + .../bitset.inclusions.compile.pass.cpp | 29 + .../chrono.inclusions.compile.pass.cpp | 28 + .../cinttypes.inclusions.compile.pass.cpp | 26 + .../complex.h.inclusions.compile.pass.cpp | 26 + .../coroutine.inclusions.compile.pass.cpp | 28 + .../deque.inclusions.compile.pass.cpp | 29 + .../filesystem.inclusions.compile.pass.cpp | 29 + .../forward_list.inclusions.compile.pass.cpp | 29 + .../ios.inclusions.compile.pass.cpp | 28 + .../iostream.inclusions.compile.pass.cpp | 37 + .../iterator.inclusions.compile.pass.cpp | 29 + .../list.inclusions.compile.pass.cpp | 29 + .../map.inclusions.compile.pass.cpp | 29 + .../memory.inclusions.compile.pass.cpp | 26 + .../optional.inclusions.compile.pass.cpp | 28 + .../queue.inclusions.compile.pass.cpp | 29 + .../random.inclusions.compile.pass.cpp | 26 + .../ranges.inclusions.compile.pass.cpp | 35 + .../regex.inclusions.compile.pass.cpp | 31 + .../set.inclusions.compile.pass.cpp | 29 + .../stack.inclusions.compile.pass.cpp | 29 + .../string.inclusions.compile.pass.cpp | 29 + .../string_view.inclusions.compile.pass.cpp | 28 + .../system_error.inclusions.compile.pass.cpp | 28 + .../tgmath.h.inclusions.compile.pass.cpp | 29 + .../thread.inclusions.compile.pass.cpp | 29 + .../tuple.inclusions.compile.pass.cpp | 28 + .../typeindex.inclusions.compile.pass.cpp | 26 + .../unordered_map.inclusions.compile.pass.cpp | 31 + .../unordered_set.inclusions.compile.pass.cpp | 31 + .../utility.inclusions.compile.pass.cpp | 29 + .../valarray.inclusions.compile.pass.cpp | 26 + .../variant.inclusions.compile.pass.cpp | 28 + .../vector.inclusions.compile.pass.cpp | 29 + .../fopen.fail.cpp | 18 - .../rename.fail.cpp | 18 - .../fstreams/filebuf/traits_mismatch.fail.cpp | 1 - .../ifstream.cons/wchar_pointer.pass.cpp | 2 + .../open_wchar_pointer.pass.cpp | 2 + .../fstreams/traits_mismatch.fail.cpp | 1 - .../input.output/file.streams/lit.local.cfg | 6 + .../last_write_time.pass.cpp | 99 + .../last_write_time.sh.cpp | 92 - .../class.path/path.itr/iterator_db.pass.cpp | 7 +- ...erse_iterator_produces_diagnostic.fail.cpp | 30 - .../path.native.obs/string_alloc.pass.cpp | 172 + .../class.path/path.req/is_pathable.pass.cpp | 8 +- .../filesystems/convert_file_time.pass.cpp | 308 + .../filesystems/convert_file_time.sh.cpp | 308 - .../input.output/filesystems/lit.local.cfg | 9 +- .../input.streams/traits_mismatch.fail.cpp | 3 +- .../iostream.format/lit.local.cfg | 6 + .../output.streams/traits_mismatch.fail.cpp | 3 +- .../iostream.objects/lit.local.cfg | 6 + .../ios/iostate.flags/clear.abort.pass.cpp | 2 +- .../input.output/iostreams.base/lit.local.cfg | 6 + .../input.output/stream.buffers/lit.local.cfg | 6 + .../input.output/string.streams/lit.local.cfg | 6 + .../string.streams/traits_mismatch.fail.cpp | 3 +- test/libcxx/iterators/advance.debug1.pass.cpp | 12 +- .../iterators/contiguous_iterators.pass.cpp | 265 + test/libcxx/iterators/failed.pass.cpp | 3 +- .../subsumption.compile.pass.cpp | 30 + ...cy_bidirectional_iterator.compile.pass.cpp | 163 + .../legacy_forward_iterator.compile.pass.cpp | 163 + .../legacy_input_iterator.compile.pass.cpp | 163 + .../legacy_iterator.compile.pass.cpp | 163 + ...cy_random_access_iterator.compile.pass.cpp | 163 + .../locale_dependent.compile.pass.cpp | 51 + .../cpp20_iter_concepts.pass.cpp | 88 + .../cpp20_iter_traits.compile.pass.cpp | 34 + .../integer_like.compile.pass.cpp | 52 + .../contiguous_iterator.verify.cpp | 55 + test/libcxx/iterators/next.debug1.pass.cpp | 10 +- test/libcxx/iterators/prev.debug1.pass.cpp | 10 +- .../iterators/trivial_iterators.pass.cpp | 189 - .../cxa_deleted_virtual.pass.cpp | 11 +- .../has_c11_features.pass.cpp | 33 - .../aligned_alloc_availability.verify.cpp | 53 + .../support.dynamic/libcpp_deallocate.sh.cpp | 48 +- .../new_faligned_allocation.pass.cpp | 91 + .../new_faligned_allocation.sh.cpp | 92 - ...ype_info.comparison.apple.compile.pass.cpp | 30 + .../type_info.comparison.merged.sh.cpp | 48 + .../type_info.comparison.unmerged.sh.cpp | 45 + .../timespec_get.xopen.compile.pass.cpp | 18 + test/libcxx/libcpp_alignof.pass.cpp | 1 - test/libcxx/libcpp_freestanding.sh.cpp | 20 + test/libcxx/libcpp_version.pass.cpp | 1 - test/libcxx/lint/lint_cmakelists.sh.py | 31 + test/libcxx/lint/lint_headers.sh.py | 52 + test/libcxx/lint/lint_modulemap.sh.py | 42 + test/libcxx/lint/lit.local.cfg | 3 + test/libcxx/localization/lit.local.cfg | 6 + .../locales/locale.abort.pass.cpp | 2 +- .../locales/locale.category.abort.pass.cpp | 2 +- .../conversions.string/ctor_move.pass.cpp | 9 +- .../locale.facet/no_allocation.pass.cpp | 23 + .../locales/use_facet.abort.pass.cpp | 2 +- .../aligned_allocation_macro.compile.pass.cpp | 20 + .../memory/aligned_allocation_macro.pass.cpp | 34 - .../allocator_void.trivial.compile.pass.cpp | 34 + .../memory/allocator_volatile.verify.cpp | 14 + .../compressed_pair/compressed_pair.pass.cpp | 51 + test/libcxx/memory/is_allocator.pass.cpp | 2 +- .../trivial_abi/shared_ptr_arg.pass.cpp | 51 + .../trivial_abi/unique_ptr_arg.pass.cpp | 52 + .../trivial_abi/unique_ptr_array.pass.cpp | 55 + .../unique_ptr_destruction_order.pass.cpp | 64 + .../trivial_abi/unique_ptr_ret.pass.cpp | 58 + .../memory/trivial_abi/weak_ptr_ret.pass.cpp | 60 + test/libcxx/min_max_macros.compile.pass.cpp | 382 + test/libcxx/min_max_macros.sh.cpp | 283 - .../minimal_cxx11_configuration.pass.cpp | 1 - test/libcxx/modules/cinttypes_exports.sh.cpp | 26 - test/libcxx/modules/clocale_exports.sh.cpp | 29 - test/libcxx/modules/cstdint_exports.sh.cpp | 26 - test/libcxx/modules/inttypes_h_exports.sh.cpp | 25 - test/libcxx/modules/stdint_h_exports.sh.cpp | 21 - test/libcxx/nasty_macros.compile.pass.cpp | 354 + .../libcxx/no_assert_include.compile.pass.cpp | 243 + test/libcxx/no_assert_include.sh.cpp | 171 - test/libcxx/numerics/bit.ops.pass.cpp | 13 +- .../numerics/c.math/constexpr-fns.pass.cpp | 6 +- .../c.math/fdelayed-template-parsing.pass.cpp | 28 + .../c.math/fdelayed-template-parsing.sh.cpp | 29 - .../numerics/c.math/undef_min_max.pass.cpp | 4 +- test/libcxx/numerics/cfenv/version.pass.cpp | 2 - .../numerics/clamp_to_integral.pass.cpp | 6 +- .../numeric.ops/midpoint.integer.pass.cpp | 6 +- .../has-no-random-device.verify.cpp | 19 + .../has-no-incomplete-ranges.compile.pass.cpp | 40 + .../range.access/end.incomplete_type.pass.cpp | 46 + .../range.all/all.nodiscard.verify.cpp | 23 + .../adaptor.nodiscard.verify.cpp | 23 + .../range.copy.wrap/arrow.pass.cpp | 56 + .../range.copy.wrap/assign.copy.pass.cpp | 170 + .../range.copy.wrap/assign.move.pass.cpp | 228 + .../range.copy.wrap/ctor.default.pass.cpp | 67 + .../range.copy.wrap/ctor.in_place.pass.cpp | 69 + .../range.copy.wrap/deref.pass.cpp | 54 + .../range.copy.wrap/has_value.pass.cpp | 50 + .../no_unique_address.pass.cpp | 58 + .../properties.compile.pass.cpp | 47 + .../range.adaptors/range.copy.wrap/types.h | 160 + .../adaptor.nodiscard.verify.cpp | 21 + .../adaptor.nodiscard.verify.cpp | 23 + .../adaptor.nodiscard.verify.cpp | 25 + .../range.nonprop.cache/assign.copy.pass.cpp | 104 + .../range.nonprop.cache/assign.move.pass.cpp | 100 + .../constraints.compile.pass.cpp | 30 + .../range.nonprop.cache/ctor.copy.pass.cpp | 75 + .../range.nonprop.cache/ctor.default.pass.cpp | 43 + .../range.nonprop.cache/ctor.move.pass.cpp | 66 + .../ranges/range.nonprop.cache/deref.pass.cpp | 55 + .../range.nonprop.cache/emplace.pass.cpp | 97 + .../range.nonprop.cache/emplace_from.pass.cpp | 79 + .../range.nonprop.cache/has_value.pass.cpp | 48 + .../different_from.compile.pass.cpp | 29 + .../has_arrow.compile.pass.cpp | 83 + .../simple_view.compile.pass.cpp | 52 + test/libcxx/ranges/version.compile.pass.cpp | 22 + .../substitutes-in-compile-flags.sh.cpp | 18 + .../substitutes-in-run.sh.cpp | 15 + .../compile-error.compile.fail.cpp | 14 + .../compile-success.compile.fail.cpp | 13 + .../compile-error.compile.pass.cpp | 16 + .../compile-success.compile.pass.cpp | 11 + .../link-error.compile.pass.cpp | 16 + .../run-error.compile.pass.cpp | 13 + .../build_run.sh.cpp | 23 + test/libcxx/selftest/dsl/dsl.sh.py | 471 + test/libcxx/selftest/dsl/lit.local.cfg | 18 + .../fail.cpp/compile-failure.fail.cpp | 15 + .../fail.cpp/compile-success.fail.cpp | 16 + .../fail.cpp/no-diagnostics-unmarked.fail.cpp | 19 + .../selftest/fail.cpp/no-diagnostics.fail.cpp | 14 + .../fail.cpp/right-diagnostic.fail.cpp | 17 + .../fail.cpp/wrong-diagnostic.fail.cpp | 18 + .../selftest/file_dependencies/a.txt} | 0 .../absolute-and-relative-paths.sh.cpp | 15 + .../selftest/file_dependencies/dir/b.txt} | 0 .../substitute-in-dependencies.sh.cpp | 12 + .../link.fail.cpp/compile-error.link.fail.cpp | 16 + .../link.fail.cpp/link-error.link.fail.cpp | 16 + .../link.fail.cpp/link-success.link.fail.cpp | 13 + .../link.pass.cpp/compile-error.link.pass.cpp | 16 + .../link.pass.cpp/link-error.link.pass.cpp | 18 + .../link.pass.cpp/link-success.link.pass.cpp | 11 + .../link.pass.cpp/run-error.link.pass.cpp | 14 + test/libcxx/selftest/not_test.sh.cpp | 16 - .../selftest/pass.cpp/compile-error.pass.cpp | 16 + .../selftest/pass.cpp/link-error.pass.cpp | 18 + .../selftest/pass.cpp/run-error.pass.cpp | 15 + .../selftest/pass.cpp/run-success.pass.cpp | 13 + test/libcxx/selftest/pass.cpp/werror.pass.cpp | 22 + .../selftest/pass.mm/compile-error.pass.mm | 18 + .../selftest/pass.mm/link-error.pass.mm | 20 + test/libcxx/selftest/pass.mm/no-arc.pass.mm | 19 + .../libcxx/selftest/pass.mm/run-error.pass.mm | 17 + .../selftest/pass.mm/run-success.pass.mm | 15 + .../pass.mm/use-objective-cxx.pass.mm | 18 + .../selftest/remote-substitutions.sh.cpp | 29 + test/libcxx/selftest/sh.cpp/empty.sh.cpp | 11 + test/libcxx/selftest/sh.cpp/run-error.sh.cpp | 13 + .../libcxx/selftest/sh.cpp/run-success.sh.cpp | 11 + .../selftest/sh.cpp/substitutions.sh.cpp | 24 + test/libcxx/selftest/sh.cpp/werror.sh.cpp | 23 + .../selftest/shell-no-escape-builtins.sh.cpp | 12 + test/libcxx/selftest/test.arc.fail.mm | 12 - test/libcxx/selftest/test.arc.pass.mm | 14 - test/libcxx/selftest/test.fail.cpp | 10 - test/libcxx/selftest/test.fail.mm | 12 - test/libcxx/selftest/test.pass.cpp | 14 - test/libcxx/selftest/test.pass.mm | 14 - test/libcxx/selftest/test.sh.cpp | 17 - test/libcxx/selftest/test_macros.pass.cpp | 31 +- test/libcxx/selftest/tmpdir-exists.sh.cpp | 11 + .../no-diagnostics-unmarked.verify.cpp | 17 + .../verify.cpp/no-diagnostics.verify.cpp | 11 + .../selftest/verify.cpp/no-werror.verify.cpp | 16 + .../verify.cpp/right-diagnostic.verify.cpp | 12 + .../verify.cpp/wrong-diagnostic.verify.cpp | 14 + .../strings/basic.string/PR42676.sh.cpp | 7 +- .../string.access/back.const.pass.cpp | 26 + .../basic.string/string.access/back.pass.cpp | 26 + .../string.access/db_back.pass.cpp | 31 + .../string.access/db_back_2.pass.cpp | 32 + .../string.access/db_cback.pass.cpp | 28 + .../string.access/db_cback_2.pass.cpp | 29 + .../string.access/db_cfront.pass.cpp | 28 + .../string.access/db_cfront_2.pass.cpp | 29 + .../string.access/db_cindex.pass.cpp | 30 + .../string.access/db_cindex_2.pass.cpp | 31 + .../string.access/db_front.pass.cpp | 31 + .../string.access/db_front_2.pass.cpp | 32 + .../string.access/db_index.pass.cpp | 30 + .../string.access/db_index_2.pass.cpp | 31 + .../string.access/front.const.pass.cpp | 27 + .../basic.string/string.access/front.pass.cpp | 27 + .../string.access/index.const.pass.cpp | 30 + .../basic.string/string.access/index.pass.cpp | 30 + .../string.capacity/PR53170.pass.cpp | 79 + .../string.cons/copy_shrunk_long.pass.cpp | 50 + .../string.iterators/db_iterators_10.pass.cpp | 30 + .../string.iterators/db_iterators_11.pass.cpp | 32 + .../string.iterators/db_iterators_12.pass.cpp | 34 + .../string.iterators/db_iterators_13.pass.cpp | 33 + .../string.iterators/db_iterators_14.pass.cpp | 33 + .../string.iterators/db_iterators_15.pass.cpp | 30 + .../string.iterators/db_iterators_2.pass.cpp | 29 + .../string.iterators/db_iterators_3.pass.cpp | 29 + .../string.iterators/db_iterators_4.pass.cpp | 31 + .../string.iterators/db_iterators_5.pass.cpp | 33 + .../string.iterators/db_iterators_6.pass.cpp | 32 + .../string.iterators/db_iterators_7.pass.cpp | 32 + .../string.iterators/db_iterators_8.pass.cpp | 29 + .../string.iterators/db_iterators_9.pass.cpp | 30 + .../clear_and_shrink.pass.cpp | 39 + .../clear_and_shrink_db1.pass.cpp | 51 - .../string.modifiers/erase_iter_db1.pass.cpp | 35 +- .../string.modifiers/erase_iter_db2.pass.cpp | 37 +- .../string.modifiers/erase_iter_db3.pass.cpp | 30 + .../string.modifiers/erase_iter_db4.pass.cpp | 32 + .../erase_iter_iter_db1.pass.cpp | 37 +- .../erase_iter_iter_db2.pass.cpp | 35 +- .../erase_iter_iter_db3.pass.cpp | 37 +- .../erase_iter_iter_db4.pass.cpp | 35 +- .../erase_iter_iter_db5.pass.cpp | 31 + .../erase_iter_iter_db6.pass.cpp | 30 + .../erase_iter_iter_db7.pass.cpp | 31 + .../erase_iter_iter_db8.pass.cpp | 30 + .../erase_pop_back_db1.pass.cpp | 19 +- .../insert_iter_char_db1.pass.cpp | 32 +- .../insert_iter_iter_iter_db1.pass.cpp | 33 + .../insert_iter_size_char_db1.pass.cpp | 23 +- .../strings/c.strings/version_cuchar.pass.cpp | 5 + .../strings/c.strings/version_cwchar.pass.cpp | 2 + .../c.strings/version_cwctype.pass.cpp | 2 + .../strings/iterators.exceptions.pass.cpp | 89 - .../strings/iterators.noexcept.pass.cpp | 82 - .../thread/atomic.availability.verify.cpp | 80 + .../thread/barrier.availability.verify.cpp | 43 + .../futures.promise/set_exception.pass.cpp | 10 +- .../set_exception_at_thread_exit.pass.cpp | 9 +- .../futures/futures.task/types.pass.cpp | 2 +- .../thread/latch.availability.verify.cpp | 26 + .../thread/semaphore.availability.verify.cpp | 51 + .../thread.barrier/version.compile.pass.cpp | 25 + ...otify_from_pthread_created_thread.pass.cpp | 10 +- .../thread.latch/version.compile.pass.cpp | 25 + .../thread.lock.guard/nodiscard.fail.cpp | 38 - .../thread.lock.guard/nodiscard.verify.cpp | 33 + .../thread_safety_lock_guard.pass.cpp | 5 +- .../thread_safety_lock_unlock.pass.cpp | 5 +- .../thread_safety_missing_unlock.fail.cpp | 5 +- ...thread_safety_requires_capability.pass.cpp | 5 +- .../thread/thread.mutex/version.pass.cpp | 2 + .../thread.semaphore/version.compile.pass.cpp | 25 + .../thread.thread.this/sleep_for.pass.cpp | 63 +- .../sleep_for.signals.pass.cpp | 72 + .../type_traits/convert_to_integral.pass.cpp | 6 +- .../is_constant_evaluated.pass.cpp | 2 +- ..._implicitly_default_constructible.pass.cpp | 5 +- .../libcxx/type_traits/is_pointer.arc.pass.mm | 49 +- .../libcxx/type_traits/is_scalar.objc.pass.mm | 38 + .../type_traits/lazy_metafunctions.pass.cpp | 2 +- test/libcxx/utilities/any/allocator.pass.cpp | 126 + .../utilities/any/size_and_alignment.pass.cpp | 2 +- test/libcxx/utilities/any/small_type.pass.cpp | 2 +- .../charconv.to.chars/availability.fail.cpp | 27 + .../format.arg/arg_t.compile.pass.cpp | 38 + .../format.arg/visit_format_arg.pass.cpp | 368 + .../format.arguments/format.args/get.pass.cpp | 318 + .../format.string.std/concepts_precision.h | 21 + .../std_format_spec_bool.pass.cpp | 452 + .../std_format_spec_char.pass.cpp | 452 + .../std_format_spec_floating_point.pass.cpp | 353 + .../std_format_spec_integer.pass.cpp | 345 + .../std_format_spec_pointer.pass.cpp | 254 + .../std_format_spec_string.pass.cpp | 369 + ...td_format_spec_string_non_unicode.pass.cpp | 112 + .../std_format_spec_string_unicode.pass.cpp | 275 + .../format.string.std/test_exception.h | 51 + .../utilities/format/version.compile.pass.cpp | 22 + .../abi_bug_cxx03_cxx11_example.sh.cpp | 14 +- .../func.bind.partial/bind_back.pass.cpp | 416 + .../func.bind.partial/compose.pass.cpp | 81 + .../function.objects/func.blocks.sh.cpp | 147 + .../func.require/bullet_4_5_6.pass.cpp | 2 +- .../func.wrap/depr_in_cxx03.verify.cpp | 29 + .../move_reentrant.pass.cpp | 7 +- .../nullptr_t_assign_reentrant.pass.cpp | 7 +- .../function.objects/refwrap/binary.pass.cpp | 2 + .../function.objects/refwrap/unary.pass.cpp | 2 + ...h_ubsan_unsigned_overflow_ignored.pass.cpp | 2 +- .../pointer.conversion/to_address.pass.cpp | 157 + .../to_address_on_funcptr.verify.cpp | 20 + .../to_address_on_function.verify.cpp | 20 + .../to_address_std_iterators.pass.cpp | 56 + .../get_pointer_safety_cxx03.pass.cpp | 47 - .../get_pointer_safety_new_abi.pass.cpp | 41 - .../util.smartptr/race_condition.pass.cpp | 3 +- .../function_type_default_deleter.fail.cpp | 18 +- .../libcxx.control_block_layout.pass.cpp | 163 + .../__has_operator_addressof.pass.cpp | 72 - .../missing_is_aggregate_trait.fail.cpp | 29 - .../stress_tests/stress_test_is_same.sh.cpp | 6 +- .../stress_test_metafunctions.sh.cpp | 10 +- .../stress_test_variant_overloads_impl.sh.cpp | 9 +- .../utilities/optional/block.objc.pass.mm | 28 + .../optional.object.assign/copy.pass.cpp | 3 +- .../optional.object.assign/move.pass.cpp | 3 +- .../optional.object.ctor/copy.pass.cpp | 2 +- .../optional.object.ctor/move.pass.cpp | 2 +- .../dereference.pass.cpp | 28 + .../dereference_const.pass.cpp | 28 + .../dereference_const_rvalue.pass.cpp | 28 + .../dereference_rvalue.pass.cpp | 28 + .../optional.object.observe/op_arrow.pass.cpp | 32 + .../op_arrow_const.pass.cpp | 32 + .../optional.object/triviality.abi.pass.cpp | 2 +- .../date.time/asctime.thread-unsafe.fail.cpp | 19 - .../date.time/ctime.thread-unsafe.fail.cpp | 19 - .../date.time/gmtime.thread-unsafe.fail.cpp | 19 - .../localtime.thread-unsafe.fail.cpp | 19 - test/libcxx/utilities/transaction.pass.cpp | 159 + .../tuple/tuple.tuple/empty_member.pass.cpp | 2 +- .../tuple.assign/array.extension.pass.cpp | 104 + .../tuple_array_template_depth.pass.cpp | 37 + ...855_tuple_ref_binding_diagnostics.fail.cpp | 5 +- ...ed_arity_initialization_extension.pass.cpp | 109 - .../tuple.cnstr/empty_tuple_trivial.pass.cpp | 22 - ...ed_arity_initialization_extension.pass.cpp | 118 - .../utility/__is_inplace_index.pass.cpp | 2 +- .../utility/__is_inplace_type.pass.cpp | 2 +- .../utility/pairs/pairs.pair/U_V.pass.cpp | 2 +- .../pairs.pair/assign_tuple_like.pass.cpp | 2 +- .../const_first_const_second.pass.cpp | 2 +- .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 2 +- .../utility/pairs/pairs.pair/default.pass.cpp | 2 +- .../non_trivial_copy_move_ABI.pass.cpp | 2 +- .../pairs.pair/pair.tuple_element.fail.cpp | 2 +- .../pairs/pairs.pair/piecewise.pass.cpp | 2 +- .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 2 +- .../variant_alternative.fail.cpp | 2 +- .../variant.variant/variant_size.pass.cpp | 3 +- .../apple/system-install-properties.sh.cpp | 45 + test/lit.cfg | 54 - test/lit.cfg.py | 10 + test/lit.site.cfg.in | 45 - test/nothing_to_do.pass.cpp | 13 - .../alg.copy/copy.pass.cpp | 109 +- .../alg.copy/copy_backward.pass.cpp | 66 +- .../alg.copy/copy_if.pass.cpp | 102 +- .../alg.copy/copy_n.pass.cpp | 100 +- .../alg.fill/fill_n.pass.cpp | 61 +- .../alg.generate/generate_n.pass.cpp | 2 +- .../contiguous_trivial_optimization.pass.cpp | 106 + .../alg.move/move.pass.cpp | 104 +- .../alg.move/move_backward.pass.cpp | 44 +- .../alg.partitions/is_partitioned.pass.cpp | 26 +- .../alg.partitions/partition.pass.cpp | 16 +- .../alg.partitions/partition_copy.pass.cpp | 4 +- .../alg.partitions/partition_point.pass.cpp | 2 +- .../alg.partitions/stable_partition.pass.cpp | 2 +- .../alg.random.sample/sample.fail.cpp | 10 +- .../alg.random.sample/sample.pass.cpp | 12 +- .../alg.random.sample/sample.stable.pass.cpp | 4 +- .../random_shuffle.pass.cpp | 2 +- .../random_shuffle_rand.pass.cpp | 2 +- .../alg.remove/remove_copy.pass.cpp | 12 +- .../alg.remove/remove_copy_if.pass.cpp | 12 +- .../alg.replace/replace_copy.pass.cpp | 10 +- .../alg.replace/replace_copy_if.pass.cpp | 10 +- .../alg.reverse/reverse.pass.cpp | 14 +- .../alg.reverse/reverse_copy.pass.cpp | 2 +- .../alg.rotate/rotate.pass.cpp | 13 +- .../alg.rotate/rotate_copy.pass.cpp | 222 +- .../alg.shift/shift_left.pass.cpp | 128 + .../alg.shift/shift_right.pass.cpp | 127 + .../alg.transform/binary_transform.pass.cpp | 140 +- .../alg.transform/unary_transform.pass.cpp | 20 +- .../alg.unique/unique_copy.pass.cpp | 10 +- .../alg.unique/unique_copy_pred.pass.cpp | 10 +- .../nothing_to_do.pass.cpp | 13 - .../alg.all_of/all_of.pass.cpp | 18 +- .../alg.any_of/any_of.pass.cpp | 26 +- .../alg.nonmodifying/alg.count/count.pass.cpp | 12 +- .../alg.count/count_if.pass.cpp | 12 +- .../alg.nonmodifying/alg.equal/equal.pass.cpp | 38 +- .../alg.equal/equal_pred.pass.cpp | 38 +- .../alg.find.first.of/find_first_of.pass.cpp | 24 +- .../find_first_of_pred.pass.cpp | 24 +- .../alg.nonmodifying/alg.find/find.pass.cpp | 8 +- .../alg.find/find_if.pass.cpp | 10 +- .../alg.find/find_if_not.pass.cpp | 10 +- .../alg.foreach/for_each_n.pass.cpp | 4 +- .../alg.foreach/test.pass.cpp | 4 +- .../alg.none_of/none_of.pass.cpp | 24 +- .../alg.search/search.pass.cpp | 24 + .../mismatch/mismatch.pass.cpp | 4 +- .../mismatch/mismatch_pred.pass.cpp | 4 +- .../alg.nonmodifying/nothing_to_do.pass.cpp | 13 - .../alg.binary.search/nothing_to_do.pass.cpp | 13 - .../alg.sorting/alg.clamp/clamp.comp.pass.cpp | 2 +- .../alg.sorting/alg.clamp/clamp.pass.cpp | 2 +- .../make.heap/make_heap.pass.cpp | 62 +- .../make.heap/make_heap_comp.pass.cpp | 111 +- .../nothing_to_do.pass.cpp | 13 - .../pop.heap/pop_heap.pass.cpp | 64 +- .../pop.heap/pop_heap_comp.pass.cpp | 88 +- .../push.heap/push_heap.pass.cpp | 59 +- .../push.heap/push_heap_comp.pass.cpp | 78 +- .../sort.heap/sort_heap.pass.cpp | 66 +- .../sort.heap/sort_heap_comp.pass.cpp | 88 +- .../lexicographical_compare.pass.cpp | 18 +- .../lexicographical_compare_comp.pass.cpp | 18 +- .../alg.merge/inplace_merge.pass.cpp | 2 +- .../alg.merge/inplace_merge_comp.pass.cpp | 6 +- .../alg.sorting/alg.merge/merge.pass.cpp | 277 +- .../alg.sorting/alg.merge/merge_comp.pass.cpp | 291 +- .../alg.min.max/max_init_list.pass.cpp | 2 +- .../alg.min.max/max_init_list_comp.pass.cpp | 2 +- .../alg.min.max/min_init_list.pass.cpp | 2 +- .../alg.min.max/min_init_list_comp.pass.cpp | 2 +- .../alg.min.max/minmax_init_list.pass.cpp | 2 +- .../minmax_init_list_comp.pass.cpp | 2 +- .../requires_forward_iterator.fail.cpp | 8 +- .../alg.nth.element/nth_element.pass.cpp | 103 +- .../alg.nth.element/nth_element_comp.pass.cpp | 115 +- .../next_permutation.pass.cpp | 15 +- .../next_permutation_comp.pass.cpp | 15 +- .../prev_permutation.pass.cpp | 15 +- .../prev_permutation_comp.pass.cpp | 15 +- .../includes/includes.pass.cpp | 52 +- .../includes/includes_comp.pass.cpp | 84 +- .../alg.set.operations/nothing_to_do.pass.cpp | 13 - .../set.difference/set_difference.pass.cpp | 237 +- .../set_difference_comp.pass.cpp | 238 +- .../set_intersection.pass.cpp | 253 +- .../set_intersection_comp.pass.cpp | 255 +- .../set_symmetric_difference.pass.cpp | 238 +- .../set_symmetric_difference_comp.pass.cpp | 241 +- .../set.union/set_union.pass.cpp | 239 +- .../set.union/set_union_comp.pass.cpp | 236 +- .../set.union/set_union_move.pass.cpp | 2 +- .../alg.sort/nothing_to_do.pass.cpp | 13 - .../partial_sort_copy.pass.cpp | 124 +- .../partial_sort_copy_comp.pass.cpp | 127 +- .../partial.sort/partial_sort.pass.cpp | 93 +- .../partial.sort/partial_sort_comp.pass.cpp | 109 +- .../alg.sorting/alg.sort/sort/sort.pass.cpp | 78 +- .../alg.sort/sort/sort_constexpr.pass.cpp | 116 + .../sort/sort_constexpr_comp.pass.cpp | 117 + .../alg.sorting/nothing_to_do.pass.cpp | 13 - .../algorithms/alg.sorting/sortable_helpers.h | 78 + .../in_in_out_result.pass.cpp | 108 + .../algorithms.results/in_in_result.pass.cpp | 89 + .../in_out_result.compile.pass.cpp | 28 + .../algorithms.results/in_out_result.pass.cpp | 133 + .../no_unique_address.compile.pass.cpp | 37 + .../robust_against_adl.compile.pass.cpp | 223 + .../robust_against_adl_on_new.pass.cpp | 37 + ...robust_re_difference_type.compile.pass.cpp | 259 + .../atomic_signal_fence.pass.cpp | 2 - .../atomic_thread_fence.pass.cpp | 2 - .../atomics.flag/atomic_flag_clear.pass.cpp | 2 - .../atomic_flag_clear_explicit.pass.cpp | 2 - .../atomics.flag/atomic_flag_test.pass.cpp | 39 + .../atomic_flag_test_and_set.pass.cpp | 2 - ...atomic_flag_test_and_set_explicit.pass.cpp | 2 - .../atomic_flag_test_explicit.pass.cpp | 113 + test/std/atomics/atomics.flag/clear.pass.cpp | 2 - ....fail.cpp => copy_assign.compile.fail.cpp} | 0 ...or.fail.cpp => copy_ctor.compile.fail.cpp} | 0 ... => copy_volatile_assign.compile.fail.cpp} | 0 .../std/atomics/atomics.flag/default.pass.cpp | 2 - test/std/atomics/atomics.flag/init.pass.cpp | 6 +- .../atomics.flag/test_and_set.pass.cpp | 2 - .../atomics.general/nothing_to_do.pass.cpp | 14 - .../replace_failure_order.pass.cpp | 2 - .../replace_failure_order_codegen.sh.cpp | 37 + .../isalwayslockfree.pass.cpp | 16 +- .../atomics.lockfree/lockfree.pass.cpp | 8 +- .../atomics.order/kill_dependency.pass.cpp | 2 - .../atomics.order/memory_order.pass.cpp | 2 - .../atomics.order/memory_order_new.pass.cpp | 4 +- .../atomics.syn/nothing_to_do.pass.cpp | 1 - .../atomics.types.generic/address.pass.cpp | 9 +- .../atomics.types.generic/bool.pass.cpp | 14 - .../constexpr_noexcept.compile.pass.cpp | 40 + .../copy_semantics_traits.pass.cpp | 45 + .../cstdint_typedefs.pass.cpp | 2 - .../atomics.types.generic/integral.pass.cpp | 17 +- .../integral_typedefs.pass.cpp | 10 +- .../standard_layout.compile.pass.cpp | 34 + .../atomics.types.generic/throw.pass.cpp | 30 + .../trivially_copyable.fail.cpp | 71 - .../trivially_copyable.pass.cpp | 73 +- .../trivially_copyable.verify.cpp | 31 + .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../atomic_compare_exchange_strong.pass.cpp | 23 +- ..._compare_exchange_strong_explicit.pass.cpp | 30 +- .../atomic_compare_exchange_weak.pass.cpp | 23 +- ...ic_compare_exchange_weak_explicit.pass.cpp | 30 +- .../atomic_exchange.pass.cpp | 18 +- .../atomic_exchange_explicit.pass.cpp | 20 +- .../atomic_fetch_add.pass.cpp | 51 +- .../atomic_fetch_add_explicit.pass.cpp | 57 +- .../atomic_fetch_and.pass.cpp | 24 +- .../atomic_fetch_and_explicit.pass.cpp | 26 +- .../atomic_fetch_or.pass.cpp | 24 +- .../atomic_fetch_or_explicit.pass.cpp | 26 +- .../atomic_fetch_sub.pass.cpp | 51 +- .../atomic_fetch_sub_explicit.pass.cpp | 56 +- .../atomic_fetch_xor.pass.cpp | 24 +- .../atomic_fetch_xor_explicit.pass.cpp | 26 +- .../atomic_helpers.h | 67 - .../atomic_init.pass.cpp | 13 +- .../atomic_is_lock_free.pass.cpp | 35 +- .../atomic_load.pass.cpp | 18 +- .../atomic_load_explicit.pass.cpp | 18 +- .../atomic_store.pass.cpp | 11 +- .../atomic_store_explicit.pass.cpp | 13 +- .../atomic_var_init.pass.cpp | 6 +- .../copy.assign.ptr.volatile.verify.cpp | 22 + .../copy.assign.volatile.verify.cpp | 22 + .../ctor.pass.cpp | 52 +- .../dtor.pass.cpp | 36 + .../nothing_to_do.pass.cpp | 1 - .../atomic_notify_all.pass.cpp | 79 + .../atomic_notify_one.pass.cpp | 67 + .../atomic_wait.pass.cpp | 70 + .../atomic_wait_explicit.pass.cpp | 72 + .../nothing_to_do.pass.cpp | 14 - test/std/atomics/types.pass.cpp | 185 + .../equivalence_relation.compile.pass.cpp | 59 + .../equivalence_relation.pass.cpp | 61 + ...ence_relation.subsumption.compile.pass.cpp | 85 + .../equivalence_relation.subsumption.pass.cpp | 61 + .../invocable.compile.pass.cpp | 413 + .../predicate.compile.pass.cpp | 64 + .../concept.predicate/predicate.pass.cpp | 66 + .../predicate.subsumption.compile.pass.cpp | 31 + .../predicate.subsumption.pass.cpp | 33 + .../regular_invocable.compile.pass.cpp | 461 + .../relation.compile.pass.cpp | 57 + .../concept.relation/relation.pass.cpp | 59 + .../relation.subsumption.compile.pass.cpp | 64 + .../relation.subsumption.pass.cpp | 41 + .../strict_weak_order.compile.pass.cpp | 58 + .../strict_weak_order.pass.cpp | 60 + ...ct_weak_order.subsumption.compile.pass.cpp | 85 + .../strict_weak_order.subsumption.pass.cpp | 40 + .../equality_comparable.compile.pass.cpp | 159 + .../equality_comparable_with.compile.pass.cpp | 1123 ++ .../totally_ordered.pass.cpp | 175 + .../totally_ordered_with.pass.cpp | 1142 ++ .../assignable_from.compile.pass.cpp | 106 + .../common_with.compile.pass.cpp | 995 ++ .../common_reference.compile.pass.cpp | 348 + .../constructible_from.compile.pass.cpp | 153 + .../convertible_to.pass.cpp | 422 + .../copy_constructible.compile.pass.cpp | 177 + .../default_initializable.compile.pass.cpp | 265 + .../default_initializable.verify.cpp | 74 + .../concept.derived/derived_from.pass.cpp | 498 + .../destructible.compile.pass.cpp | 79 + .../move_constructible.compile.pass.cpp | 81 + .../concept.same/same_as.pass.cpp | 296 + .../concept.swappable/swappable.pass.cpp | 308 + .../swappable_with.compile.pass.cpp | 686 + .../concepts.arithmetic/arithmetic.h | 37 + .../floating_point.pass.cpp | 79 + .../concepts.arithmetic/integral.pass.cpp | 93 + .../signed_integral.pass.cpp | 97 + .../unsigned_integral.pass.cpp | 98 + .../concepts.object/copyable.compile.pass.cpp | 118 + .../concepts.object/movable.compile.pass.cpp | 137 + .../concepts.object/regular.compile.pass.cpp | 168 + .../semiregular.compile.pass.cpp | 131 + test/std/containers/Copyable.h | 2 +- test/std/containers/Emplaceable.h | 4 +- test/std/containers/NotConstructible.h | 2 +- ...PR28469_undefined_behavior_segfault.sh.cpp | 8 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../associative/map/compare.pass.cpp | 4 +- .../associative/map/get_allocator.pass.cpp | 37 + ...rator_concept_conformance.compile.pass.cpp | 50 + .../associative/map/map.access/empty.fail.cpp | 29 - .../map/map.access/empty.verify.cpp | 27 + .../map/map.access/index_rv_key.pass.cpp | 2 +- .../map/map.access/index_tuple.pass.cpp | 19 +- .../map.cons/assign_initializer_list.pass.cpp | 13 +- .../associative/map/map.cons/compare.pass.cpp | 6 +- .../map/map.cons/compare_alloc.pass.cpp | 6 +- ...mpare_copy_constructible.compile.fail.cpp} | 0 .../associative/map/map.cons/copy.pass.cpp | 6 +- .../map/map.cons/copy_alloc.pass.cpp | 6 +- .../copy_assign.addressof.compile.pass.cpp | 33 + .../map/map.cons/copy_assign.pass.cpp | 53 +- .../associative/map/map.cons/deduct.fail.cpp | 6 +- .../associative/map/map.cons/deduct.pass.cpp | 25 +- .../map/map.cons/deduct_const.pass.cpp | 3 +- .../map/map.cons/default_noexcept.pass.cpp | 2 +- .../map/map.cons/default_recursive.pass.cpp | 9 +- .../map/map.cons/dtor_noexcept.pass.cpp | 2 +- .../map/map.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_compare.pass.cpp | 6 +- .../initializer_list_compare_alloc.pass.cpp | 10 +- .../map/map.cons/iter_iter_comp.pass.cpp | 4 +- .../map.cons/iter_iter_comp_alloc.pass.cpp | 8 +- .../associative/map/map.cons/move.pass.cpp | 10 +- .../map/map.cons/move_alloc.pass.cpp | 12 +- .../map/map.cons/move_assign.pass.cpp | 12 +- .../map.cons/move_assign_noexcept.pass.cpp | 2 +- .../map/map.cons/move_noexcept.pass.cpp | 2 +- .../map/map.erasure/erase_if.pass.cpp | 46 +- .../map/map.modifiers/emplace.pass.cpp | 2 +- .../map/map.modifiers/emplace_hint.pass.cpp | 2 +- .../map.modifiers/extract_iterator.pass.cpp | 2 +- .../map/map.modifiers/extract_key.pass.cpp | 2 +- ...nd_emplace_allocator_requirements.pass.cpp | 2 +- .../insert_initializer_list.pass.cpp | 2 +- .../map.modifiers/insert_iter_iter.pass.cpp | 4 +- .../map/map.modifiers/insert_iter_rv.pass.cpp | 2 +- .../map.modifiers/insert_node_type.pass.cpp | 2 +- .../insert_node_type_hint.pass.cpp | 2 +- .../map.modifiers/insert_or_assign.pass.cpp | 106 +- .../map/map.modifiers/insert_rv.pass.cpp | 2 +- .../map/map.modifiers/merge.pass.cpp | 2 +- .../map/map.modifiers/try.emplace.pass.cpp | 2 +- .../map/map.nonmember/op_compare.pass.cpp | 81 + .../map/map.observers/key_comp.pass.cpp | 30 + .../map/map.observers/value_comp.pass.cpp | 30 + .../map/{ => map.ops}/contains.pass.cpp | 3 +- .../map/map.ops/contains_transparent.pass.cpp | 48 + .../associative/map/map.ops/count0.pass.cpp | 5 +- .../map/map.ops/count1.compile.fail.cpp | 38 + .../associative/map/map.ops/count1.fail.cpp | 39 - .../map/map.ops/count2.compile.fail.cpp | 38 + .../associative/map/map.ops/count2.fail.cpp | 39 - .../map/map.ops/count3.compile.fail.cpp | 38 + .../associative/map/map.ops/count3.fail.cpp | 39 - .../map/map.ops/count_transparent.pass.cpp | 6 +- .../map/map.ops/equal_range0.pass.cpp | 6 +- .../map/map.ops/equal_range1.compile.fail.cpp | 39 + .../map/map.ops/equal_range1.fail.cpp | 39 - .../map/map.ops/equal_range2.compile.fail.cpp | 39 + .../map/map.ops/equal_range2.fail.cpp | 39 - .../map/map.ops/equal_range3.compile.fail.cpp | 39 + .../map/map.ops/equal_range3.fail.cpp | 39 - .../map.ops/equal_range_transparent.pass.cpp | 6 +- .../associative/map/map.ops/find0.pass.cpp | 2 +- ...{find1.fail.cpp => find1.compile.fail.cpp} | 0 ...{find2.fail.cpp => find2.compile.fail.cpp} | 0 ...{find3.fail.cpp => find3.compile.fail.cpp} | 0 .../map/map.ops/lower_bound0.pass.cpp | 2 +- ...fail.cpp => lower_bound1.compile.fail.cpp} | 0 ...fail.cpp => lower_bound2.compile.fail.cpp} | 0 ...fail.cpp => lower_bound3.compile.fail.cpp} | 0 .../map/map.ops/upper_bound0.pass.cpp | 2 +- ...fail.cpp => upper_bound1.compile.fail.cpp} | 0 ...fail.cpp => upper_bound2.compile.fail.cpp} | 0 ...fail.cpp => upper_bound3.compile.fail.cpp} | 0 .../map/map.special/non_member_swap.pass.cpp | 6 +- .../map/map.special/swap_noexcept.pass.cpp | 2 +- .../map/map.value_compare/invoke.pass.cpp | 47 + .../map/map.value_compare/types.pass.cpp | 30 + ...range_concept_conformance.compile.pass.cpp | 39 + ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../associative/multimap/empty.fail.cpp | 29 - .../associative/multimap/empty.verify.cpp | 27 + .../multimap/get_allocator.pass.cpp | 37 + ...rator_concept_conformance.compile.pass.cpp | 50 + .../assign_initializer_list.pass.cpp | 2 +- .../multimap/multimap.cons/compare.pass.cpp | 6 +- .../multimap.cons/compare_alloc.pass.cpp | 6 +- ...mpare_copy_constructible.compile.fail.cpp} | 0 .../multimap/multimap.cons/copy.pass.cpp | 6 +- .../multimap.cons/copy_alloc.pass.cpp | 6 +- .../copy_assign.addressof.compile.pass.cpp | 33 + .../multimap.cons/copy_assign.pass.cpp | 6 +- .../multimap/multimap.cons/deduct.fail.cpp | 6 +- .../multimap/multimap.cons/deduct.pass.cpp | 25 +- .../multimap.cons/deduct_const.pass.cpp | 3 +- .../multimap.cons/default_noexcept.pass.cpp | 2 +- .../multimap.cons/default_recursive.pass.cpp | 9 +- .../multimap.cons/dtor_noexcept.pass.cpp | 2 +- .../multimap.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_compare.pass.cpp | 6 +- .../initializer_list_compare_alloc.pass.cpp | 10 +- .../multimap.cons/iter_iter_comp.pass.cpp | 4 +- .../iter_iter_comp_alloc.pass.cpp | 6 +- .../multimap/multimap.cons/move.pass.cpp | 10 +- .../multimap.cons/move_alloc.pass.cpp | 12 +- .../multimap.cons/move_assign.pass.cpp | 12 +- .../move_assign_noexcept.pass.cpp | 2 +- .../multimap.cons/move_noexcept.pass.cpp | 2 +- .../multimap.erasure/erase_if.pass.cpp | 69 +- .../multimap.modifiers/emplace.pass.cpp | 2 +- .../multimap.modifiers/emplace_hint.pass.cpp | 2 +- .../extract_iterator.pass.cpp | 2 +- .../multimap.modifiers/extract_key.pass.cpp | 2 +- .../insert_allocator_requirements.pass.cpp | 2 +- .../insert_initializer_list.pass.cpp | 2 +- .../insert_iter_iter.pass.cpp | 4 +- .../insert_iter_rv.pass.cpp | 2 +- .../insert_node_type.pass.cpp | 2 +- .../insert_node_type_hint.pass.cpp | 2 +- .../multimap.modifiers/insert_rv.pass.cpp | 2 +- .../multimap.modifiers/merge.pass.cpp | 2 +- .../multimap.nonmember/op_compare.pass.cpp | 90 + .../multimap.observers/key_comp.pass.cpp | 30 + .../multimap.observers/value_comp.pass.cpp | 30 + .../multimap/multimap.ops/count0.pass.cpp | 5 +- .../multimap.ops/count1.compile.fail.cpp | 36 + .../multimap/multimap.ops/count1.fail.cpp | 37 - .../multimap.ops/count2.compile.fail.cpp | 36 + .../multimap/multimap.ops/count2.fail.cpp | 37 - .../multimap.ops/count3.compile.fail.cpp | 36 + .../multimap/multimap.ops/count3.fail.cpp | 37 - .../multimap.ops/count_transparent.pass.cpp | 6 +- .../multimap.ops/equal_range0.pass.cpp | 6 +- .../equal_range1.compile.fail.cpp | 37 + .../multimap.ops/equal_range1.fail.cpp | 37 - .../equal_range2.compile.fail.cpp | 39 + .../multimap.ops/equal_range2.fail.cpp | 39 - .../equal_range3.compile.fail.cpp | 39 + .../multimap.ops/equal_range3.fail.cpp | 39 - .../equal_range_transparent.pass.cpp | 6 +- .../multimap/multimap.ops/find0.pass.cpp | 2 +- ...{find1.fail.cpp => find1.compile.fail.cpp} | 0 ...{find2.fail.cpp => find2.compile.fail.cpp} | 0 ...{find3.fail.cpp => find3.compile.fail.cpp} | 0 .../multimap.ops/lower_bound0.pass.cpp | 2 +- ...fail.cpp => lower_bound1.compile.fail.cpp} | 0 ...fail.cpp => lower_bound2.compile.fail.cpp} | 0 ...fail.cpp => lower_bound3.compile.fail.cpp} | 0 .../multimap.ops/upper_bound0.pass.cpp | 2 +- ...fail.cpp => upper_bound1.compile.fail.cpp} | 0 ...fail.cpp => upper_bound2.compile.fail.cpp} | 0 ...fail.cpp => upper_bound3.compile.fail.cpp} | 0 .../multimap.special/non_member_swap.pass.cpp | 6 +- .../multimap.special/swap_noexcept.pass.cpp | 2 +- .../multimap.value_compare/invoke.pass.cpp | 47 + .../multimap.value_compare/types.pass.cpp | 30 + ...range_concept_conformance.compile.pass.cpp | 39 + ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../multiset/count_transparent.pass.cpp | 10 +- .../associative/multiset/emplace.pass.cpp | 2 +- .../multiset/emplace_hint.pass.cpp | 2 +- .../associative/multiset/empty.fail.cpp | 29 - .../associative/multiset/empty.verify.cpp | 27 + .../multiset/equal_range_transparent.pass.cpp | 6 +- .../multiset/extract_iterator.pass.cpp | 2 +- .../associative/multiset/extract_key.pass.cpp | 2 +- .../multiset/get_allocator.pass.cpp | 33 + ...rt_emplace_allocator_requirements.pass.cpp | 2 +- .../multiset/insert_initializer_list.pass.cpp | 2 +- .../multiset/insert_iter_iter.pass.cpp | 8 +- .../multiset/insert_iter_rv.pass.cpp | 2 +- .../multiset/insert_node_type.pass.cpp | 2 +- .../multiset/insert_node_type_hint.pass.cpp | 2 +- .../associative/multiset/insert_rv.pass.cpp | 2 +- ...rator_concept_conformance.compile.pass.cpp | 50 + .../associative/multiset/merge.pass.cpp | 2 +- .../assign_initializer_list.pass.cpp | 2 +- .../multiset/multiset.cons/compare.pass.cpp | 8 +- .../multiset.cons/compare_alloc.pass.cpp | 2 +- ...mpare_copy_constructible.compile.fail.cpp} | 0 .../multiset/multiset.cons/copy.pass.cpp | 4 +- .../multiset.cons/copy_alloc.pass.cpp | 2 +- .../copy_assign.addressof.compile.pass.cpp | 26 + .../multiset.cons/copy_assign.pass.cpp | 4 +- .../multiset/multiset.cons/deduct.fail.cpp | 6 +- .../multiset/multiset.cons/deduct.pass.cpp | 8 +- .../multiset.cons/default_noexcept.pass.cpp | 2 +- .../multiset.cons/dtor_noexcept.pass.cpp | 2 +- .../multiset.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_compare.pass.cpp | 4 +- .../initializer_list_compare_alloc.pass.cpp | 4 +- .../multiset/multiset.cons/iter_iter.pass.cpp | 8 +- .../multiset.cons/iter_iter_alloc.pass.cpp | 8 +- .../multiset.cons/iter_iter_comp.pass.cpp | 6 +- .../multiset/multiset.cons/move.pass.cpp | 8 +- .../multiset.cons/move_alloc.pass.cpp | 8 +- .../multiset.cons/move_assign.pass.cpp | 12 +- .../move_assign_noexcept.pass.cpp | 2 +- .../multiset.cons/move_noexcept.pass.cpp | 2 +- .../multiset.erasure/erase_if.pass.cpp | 63 +- .../multiset.nonmember/op_compare.pass.cpp | 74 + .../multiset/multiset.observers/comp.pass.cpp | 33 + .../multiset.special/non_member_swap.pass.cpp | 4 +- .../multiset.special/swap_noexcept.pass.cpp | 2 +- ...range_concept_conformance.compile.pass.cpp | 38 + ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../associative/set/contains.pass.cpp | 3 +- .../set/contains_transparent.pass.cpp | 51 + .../set/count_transparent.pass.cpp | 12 +- .../associative/set/emplace.pass.cpp | 2 +- .../associative/set/emplace_hint.pass.cpp | 2 +- .../containers/associative/set/empty.fail.cpp | 29 - .../associative/set/empty.verify.cpp | 27 + .../set/equal_range_transparent.pass.cpp | 6 +- .../associative/set/extract_iterator.pass.cpp | 2 +- .../associative/set/extract_key.pass.cpp | 2 +- .../associative/set/get_allocator.pass.cpp | 33 + ...nd_emplace_allocator_requirements.pass.cpp | 2 +- .../set/insert_initializer_list.pass.cpp | 2 +- .../associative/set/insert_iter_iter.pass.cpp | 8 +- .../associative/set/insert_iter_rv.pass.cpp | 2 +- .../associative/set/insert_node_type.pass.cpp | 2 +- .../set/insert_node_type_hint.pass.cpp | 2 +- .../associative/set/insert_rv.pass.cpp | 2 +- ...rator_concept_conformance.compile.pass.cpp | 50 + .../containers/associative/set/merge.pass.cpp | 2 +- ...range_concept_conformance.compile.pass.cpp | 41 + .../set.cons/assign_initializer_list.pass.cpp | 14 +- .../associative/set/set.cons/compare.pass.cpp | 8 +- .../set/set.cons/compare_alloc.pass.cpp | 2 +- ...mpare_copy_constructible.compile.fail.cpp} | 0 .../associative/set/set.cons/copy.pass.cpp | 4 +- .../set/set.cons/copy_alloc.pass.cpp | 2 +- .../copy_assign.addressof.compile.pass.cpp | 26 + .../set/set.cons/copy_assign.pass.cpp | 4 +- .../associative/set/set.cons/deduct.fail.cpp | 6 +- .../associative/set/set.cons/deduct.pass.cpp | 8 +- .../set/set.cons/default_noexcept.pass.cpp | 2 +- .../set/set.cons/dtor_noexcept.pass.cpp | 2 +- .../set/set.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_compare.pass.cpp | 4 +- .../initializer_list_compare_alloc.pass.cpp | 6 +- .../set/set.cons/iter_iter.pass.cpp | 8 +- .../set/set.cons/iter_iter_alloc.pass.cpp | 8 +- .../set/set.cons/iter_iter_comp.pass.cpp | 6 +- .../associative/set/set.cons/move.pass.cpp | 8 +- .../set/set.cons/move_alloc.pass.cpp | 8 +- .../set/set.cons/move_assign.pass.cpp | 12 +- .../set.cons/move_assign_noexcept.pass.cpp | 2 +- .../set/set.cons/move_noexcept.pass.cpp | 2 +- .../set/set.erasure/erase_if.pass.cpp | 41 +- .../set/set.nonmember/op_compare.pass.cpp | 65 + .../set/set.observers/comp.pass.cpp | 33 + .../set/set.special/non_member_swap.pass.cpp | 4 +- .../set/set.special/swap_noexcept.pass.cpp | 2 +- .../container.adaptors/nothing_to_do.pass.cpp | 13 - .../priqueue.cons.alloc/ctor_alloc.pass.cpp | 8 +- .../ctor_comp_alloc.pass.cpp | 12 +- .../ctor_comp_cont_alloc.pass.cpp | 12 +- .../ctor_comp_rcont_alloc.pass.cpp | 12 +- .../ctor_copy_alloc.pass.cpp | 8 +- .../ctor_iter_iter_alloc.pass.cpp | 41 + .../ctor_iter_iter_comp_alloc.pass.cpp | 42 + .../ctor_iter_iter_comp_cont_alloc.pass.cpp | 42 + .../ctor_iter_iter_comp_rcont_alloc.pass.cpp | 46 + .../ctor_move_alloc.pass.cpp | 14 +- .../assign_copy.addressof.compile.pass.cpp | 24 + .../priqueue.cons/assign_move.pass.cpp | 2 +- .../priqueue.cons/ctor_comp.pass.cpp | 14 +- .../ctor_comp_container.pass.cpp | 19 +- .../ctor_comp_rcontainer.pass.cpp | 17 +- .../priqueue.cons/ctor_default.pass.cpp | 18 +- .../ctor_iter_constraint.compile.pass.cpp | 59 + .../ctor_iter_iter_comp_rcont.pass.cpp | 2 +- .../priqueue.cons/ctor_move.pass.cpp | 2 +- .../priqueue.cons/deduct.fail.cpp | 3 +- .../priqueue.cons/deduct.pass.cpp | 268 +- .../priqueue.cons/default_noexcept.pass.cpp | 2 +- .../priqueue.cons/dtor_noexcept.pass.cpp | 2 +- .../move_assign_noexcept.pass.cpp | 2 +- .../priqueue.cons/move_noexcept.pass.cpp | 2 +- .../priqueue.members/emplace.pass.cpp | 2 +- .../priqueue.members/empty.fail.cpp | 29 - .../priqueue.members/empty.verify.cpp | 27 + .../priqueue.members/push_rvalue.pass.cpp | 2 +- .../priqueue.special/swap_noexcept.pass.cpp | 2 +- ...{types.fail.cpp => types.compile.fail.cpp} | 0 .../queue.cons.alloc/ctor_alloc.pass.cpp | 4 +- .../ctor_container_alloc.pass.cpp | 4 +- .../queue.cons.alloc/ctor_iterators.pass.cpp | 50 + .../ctor_queue_alloc.pass.cpp | 2 +- .../ctor_rcontainer_alloc.pass.cpp | 6 +- .../ctor_rqueue_alloc.pass.cpp | 6 +- .../queue/queue.cons/ctor_container.pass.cpp | 15 +- .../queue/queue.cons/ctor_default.pass.cpp | 18 +- .../queue/queue.cons/ctor_iterators.pass.cpp | 46 + .../queue/queue.cons/ctor_move.pass.cpp | 2 +- .../queue/queue.cons/ctor_rcontainer.pass.cpp | 21 +- .../queue/queue.cons/deduct.fail.cpp | 3 +- .../queue/queue.cons/deduct.pass.cpp | 121 +- .../queue.cons/default_noexcept.pass.cpp | 2 +- .../queue/queue.cons/dtor_noexcept.pass.cpp | 2 +- .../queue.cons/move_assign_noexcept.pass.cpp | 2 +- .../queue/queue.cons/move_noexcept.pass.cpp | 2 +- .../assign_copy.addressof.compile.pass.cpp | 24 + .../queue/queue.defn/assign_move.pass.cpp | 2 +- .../queue/queue.defn/emplace.pass.cpp | 2 +- .../queue/queue.defn/empty.fail.cpp | 29 - .../queue/queue.defn/empty.verify.cpp | 27 + .../queue/queue.defn/push_rv.pass.cpp | 2 +- ...{types.fail.cpp => types.compile.fail.cpp} | 0 .../queue.special/swap_noexcept.pass.cpp | 2 +- .../stack.cons.alloc/ctor_alloc.pass.cpp | 4 +- .../ctor_container_alloc.pass.cpp | 4 +- .../stack.cons.alloc/ctor_copy_alloc.pass.cpp | 2 +- .../stack.cons.alloc/ctor_iterators.pass.cpp | 50 + .../ctor_rcontainer_alloc.pass.cpp | 6 +- .../ctor_rqueue_alloc.pass.cpp | 6 +- .../stack/stack.cons/ctor_container.pass.cpp | 17 +- .../stack/stack.cons/ctor_default.pass.cpp | 18 +- .../stack/stack.cons/ctor_iterators.pass.cpp | 45 + .../stack/stack.cons/ctor_move.pass.cpp | 2 +- .../stack/stack.cons/ctor_rcontainer.pass.cpp | 19 +- .../stack/stack.cons/deduct.fail.cpp | 4 +- .../stack/stack.cons/deduct.pass.cpp | 124 +- .../stack.cons/default_noexcept.pass.cpp | 2 +- .../stack/stack.cons/dtor_noexcept.pass.cpp | 2 +- .../stack.cons/move_assign_noexcept.pass.cpp | 2 +- .../stack/stack.cons/move_noexcept.pass.cpp | 2 +- .../stack/stack.defn/assign_move.pass.cpp | 2 +- .../stack/stack.defn/emplace.pass.cpp | 2 +- .../stack/stack.defn/empty.fail.cpp | 29 - .../stack/stack.defn/empty.verify.cpp | 27 + .../stack/stack.defn/push_rv.pass.cpp | 2 +- ...{types.fail.cpp => types.compile.fail.cpp} | 0 .../stack.special/swap_noexcept.pass.cpp | 2 +- .../node_handle.nodiscard.verify.cpp | 52 + .../container.node/node_handle.pass.cpp | 32 +- .../associative.reqmts/nothing_to_do.pass.cpp | 13 - .../allocator_move.pass.cpp | 23 +- .../nothing_to_do.pass.cpp | 13 - .../nothing_to_do.pass.cpp | 13 - .../unord.req/nothing_to_do.pass.cpp | 13 - .../iterator.rel_ops.compile.pass.cpp | 143 + ...map_allocator_requirement_test_templates.h | 99 +- test/std/containers/nothing_to_do.pass.cpp | 13 - .../sequences/array/aggregate.pass.cpp | 47 + .../array/array.cons/deduct.fail.cpp | 9 +- .../array/array.cons/deduct.pass.cpp | 81 +- .../array/array.cons/default.pass.cpp | 50 - .../implicit_copy.addressof.compile.pass.cpp | 24 + .../array/array.cons/implicit_copy.pass.cpp | 153 +- .../array/array.cons/initialization.pass.cpp | 188 + .../array.cons/initializer_list.pass.cpp | 54 - .../array/array.creation/to_array.fail.cpp | 43 + .../array/array.creation/to_array.pass.cpp | 122 + .../sequences/array/array.data/data.pass.cpp | 83 +- .../array/array.data/data_const.pass.cpp | 76 +- .../sequences/array/array.fill/fill.fail.cpp | 4 - .../sequences/array/array.fill/fill.pass.cpp | 18 +- .../sequences/array/array.size/size.pass.cpp | 6 +- .../array/array.special/swap.pass.cpp | 24 +- .../sequences/array/array.swap/swap.fail.cpp | 4 - .../sequences/array/array.swap/swap.pass.cpp | 20 +- .../sequences/array/array.tuple/get.fail.cpp | 5 - .../sequences/array/array.tuple/get.pass.cpp | 83 +- .../array/array.tuple/get_const.pass.cpp | 50 +- .../array/array.tuple/get_const_rv.pass.cpp | 36 +- .../array/array.tuple/get_rv.pass.cpp | 8 +- .../array/array.tuple/tuple_element.fail.cpp | 5 - .../containers/sequences/array/at.pass.cpp | 174 +- .../sequences/array/at_const.pass.cpp | 105 + .../containers/sequences/array/begin.pass.cpp | 53 - .../sequences/array/compare.fail.cpp | 10 +- .../sequences/array/compare.pass.cpp | 87 +- .../sequences/array/contiguous.pass.cpp | 35 +- .../containers/sequences/array/empty.fail.cpp | 32 - .../containers/sequences/array/empty.pass.cpp | 47 +- .../sequences/array/empty.verify.cpp | 30 + .../sequences/array/front_back.pass.cpp | 121 +- .../sequences/array/front_back_const.pass.cpp | 68 + .../sequences/array/indexing.pass.cpp | 118 +- .../sequences/array/indexing_const.pass.cpp | 68 + ...rator_concept_conformance.compile.pass.cpp | 61 + .../sequences/array/iterators.pass.cpp | 305 +- .../sequences/array/max_size.pass.cpp | 47 +- ...range_concept_conformance.compile.pass.cpp | 39 + .../array/size_and_alignment.pass.cpp | 20 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../sequences/deque/compare.pass.cpp | 119 + .../deque/deque.capacity/empty.fail.cpp | 29 - .../deque/deque.capacity/empty.verify.cpp | 27 + .../assign_initializer_list.pass.cpp | 2 +- .../deque.cons/assign_iter_iter.pass.cpp | 4 +- .../deque/deque.cons/deduct.fail.cpp | 5 +- .../deque/deque.cons/deduct.pass.cpp | 41 +- .../deque.cons/default_noexcept.pass.cpp | 3 +- .../deque/deque.cons/dtor_noexcept.pass.cpp | 3 +- .../deque.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_alloc.pass.cpp | 2 +- .../deque/deque.cons/iter_iter.pass.cpp | 4 +- .../deque/deque.cons/iter_iter_alloc.pass.cpp | 6 +- .../sequences/deque/deque.cons/move.pass.cpp | 2 +- .../deque/deque.cons/move_alloc.pass.cpp | 2 +- .../move_assign.addressof.compile.pass.cpp | 24 + .../deque/deque.cons/move_assign.pass.cpp | 2 +- .../deque.cons/move_assign_noexcept.pass.cpp | 3 +- .../deque/deque.cons/move_noexcept.pass.cpp | 3 +- .../op_equal_initializer_list.pass.cpp | 2 +- .../deque/deque.erasure/erase.pass.cpp | 69 +- .../deque/deque.erasure/erase_if.pass.cpp | 63 +- .../deque/deque.modifiers/emplace.pass.cpp | 2 +- .../deque.modifiers/emplace_back.pass.cpp | 2 +- .../deque.modifiers/emplace_front.pass.cpp | 2 +- .../insert_iter_initializer_list.pass.cpp | 2 +- .../deque.modifiers/insert_iter_iter.pass.cpp | 10 +- .../deque.modifiers/insert_rvalue.pass.cpp | 6 +- .../push_back_exception_safety.pass.cpp | 9 +- .../deque.modifiers/push_back_rvalue.pass.cpp | 4 +- .../push_front_exception_safety.pass.cpp | 9 +- .../push_front_rvalue.pass.cpp | 4 +- .../deque/deque.special/copy.pass.cpp | 2 +- .../deque.special/swap_noexcept.pass.cpp | 4 +- .../sequences/deque/get_allocator.pass.cpp | 34 + ...rator_concept_conformance.compile.pass.cpp | 64 + ...range_concept_conformance.compile.pass.cpp | 39 + .../containers/sequences/deque/types.pass.cpp | 3 + ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../sequences/forwardlist/empty.fail.cpp | 29 - .../sequences/forwardlist/empty.verify.cpp | 27 + ...{alloc.fail.cpp => alloc.compile.fail.cpp} | 0 .../assign_copy.addressof.compile.pass.cpp | 24 + .../forwardlist.cons/assign_init.pass.cpp | 2 +- .../forwardlist.cons/assign_move.pass.cpp | 22 +- .../forwardlist.cons/assign_op_init.pass.cpp | 2 +- .../forwardlist.cons/assign_range.pass.cpp | 8 +- .../forwardlist.cons/deduct.fail.cpp | 5 +- .../forwardlist.cons/deduct.pass.cpp | 43 +- .../default_noexcept.pass.cpp | 3 +- .../forwardlist.cons/dtor_noexcept.pass.cpp | 3 +- .../forwardlist.cons/init.pass.cpp | 2 +- .../forwardlist.cons/init_alloc.pass.cpp | 2 +- .../forwardlist.cons/move.pass.cpp | 8 +- .../forwardlist.cons/move_alloc.pass.cpp | 8 +- .../move_assign_noexcept.pass.cpp | 3 +- .../forwardlist.cons/move_noexcept.pass.cpp | 3 +- .../forwardlist.cons/range.pass.cpp | 4 +- .../forwardlist.cons/range_alloc.pass.cpp | 4 +- .../forwardlist.erasure/erase.pass.cpp | 69 +- .../forwardlist.erasure/erase_if.pass.cpp | 63 +- ...rator_concept_conformance.compile.pass.cpp | 46 + .../emplace_after.pass.cpp | 2 +- .../emplace_front.pass.cpp | 2 +- .../insert_after_init.pass.cpp | 2 +- .../insert_after_range.pass.cpp | 4 +- .../insert_after_rv.pass.cpp | 2 +- .../push_front_exception_safety.pass.cpp | 2 +- .../push_front_rv.pass.cpp | 2 +- .../forwardlist.ops/merge.pass.cpp | 50 - .../merge_lvalue.addressof.compile.pass.cpp | 24 + .../forwardlist.ops/merge_lvalue.pass.cpp | 113 + ...rge_lvalue_pred.addressof.compile.pass.cpp | 24 + .../merge_lvalue_pred.pass.cpp | 114 + .../forwardlist.ops/merge_pred.pass.cpp | 51 - .../merge_rvalue.addressof.compile.pass.cpp | 26 + .../forwardlist.ops/merge_rvalue.pass.cpp | 106 + ...rge_rvalue_pred.addressof.compile.pass.cpp | 26 + .../merge_rvalue_pred.pass.cpp | 107 + .../forwardlist.ops/sort_pred.pass.cpp | 1 - .../forwardlist.spec/swap_noexcept.pass.cpp | 4 +- .../forwardlist/get_allocator.pass.cpp | 34 + ...range_concept_conformance.compile.pass.cpp | 39 + ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../sequences/list/compare.pass.cpp | 117 + .../sequences/list/get_allocator.pass.cpp | 34 + ...rator_concept_conformance.compile.pass.cpp | 64 + .../list/list.capacity/empty.fail.cpp | 29 - .../list/list.capacity/empty.verify.cpp | 27 + .../list/list.capacity/resize_size.pass.cpp | 8 +- .../assign_copy.addressof.compile.pass.cpp | 24 + .../assign_initializer_list.pass.cpp | 2 +- .../assign_move.addressof.compile.pass.cpp | 26 + .../list/list.cons/assign_move.pass.cpp | 8 +- .../sequences/list/list.cons/deduct.fail.cpp | 5 +- .../sequences/list/list.cons/deduct.pass.cpp | 39 +- .../list/list.cons/default_noexcept.pass.cpp | 3 +- .../sequences/list/list.cons/dtor.pass.cpp | 45 + .../list/list.cons/dtor_noexcept.pass.cpp | 3 +- .../list/list.cons/initializer_list.pass.cpp | 2 +- .../list.cons/initializer_list_alloc.pass.cpp | 2 +- .../list/list.cons/input_iterator.pass.cpp | 28 +- .../sequences/list/list.cons/move.pass.cpp | 8 +- .../list/list.cons/move_alloc.pass.cpp | 2 +- .../list.cons/move_assign_noexcept.pass.cpp | 3 +- .../list/list.cons/move_noexcept.pass.cpp | 3 +- .../op_equal_initializer_list.pass.cpp | 2 +- .../list/list.erasure/erase.pass.cpp | 69 +- .../list/list.erasure/erase_if.pass.cpp | 63 +- .../emplace.addressof.compile.pass.cpp | 22 + .../list/list.modifiers/emplace.pass.cpp | 2 +- .../list/list.modifiers/emplace_back.pass.cpp | 2 +- .../list.modifiers/emplace_front.pass.cpp | 2 +- .../erase_iter.addressof.compile.pass.cpp | 23 + .../insert_iter_initializer_list.pass.cpp | 2 +- ...ert_iter_rvalue.addressof.compile.pass.cpp | 25 + .../insert_iter_rvalue.pass.cpp | 2 +- ...iter_size_value.addressof.compile.pass.cpp | 20 + ...sert_iter_value.addressof.compile.pass.cpp | 20 + .../push_back_exception_safety.pass.cpp | 2 +- .../list.modifiers/push_back_rvalue.pass.cpp | 2 +- .../push_front_exception_safety.pass.cpp | 2 +- .../list.modifiers/push_front_rvalue.pass.cpp | 2 +- .../sequences/list/list.ops/merge.pass.cpp | 2 +- .../merge_comp.addressof.compile.pass.cpp | 24 + .../list/list.ops/merge_comp.pass.cpp | 2 +- ...e_pos_list_iter.addressof.compile.pass.cpp | 23 + ..._list_iter_iter.addressof.compile.pass.cpp | 23 + .../swap.addressof.compile.pass.cpp | 25 + .../sequences/list/list.special/swap.pass.cpp | 86 +- .../list/list.special/swap_noexcept.pass.cpp | 4 +- ...range_concept_conformance.compile.pass.cpp | 39 + .../containers/sequences/list/types.pass.cpp | 3 + .../sequences/nothing_to_do.pass.cpp | 13 - .../assign_initializer_list.pass.cpp | 2 +- .../vector.bool/assign_move.pass.cpp | 4 +- .../sequences/vector.bool/compare.pass.cpp | 80 + .../vector.bool/construct_iter_iter.pass.cpp | 4 +- .../construct_iter_iter_alloc.pass.cpp | 4 +- .../vector.bool/default_noexcept.pass.cpp | 2 +- .../vector.bool/dtor_noexcept.pass.cpp | 2 +- .../sequences/vector.bool/emplace.pass.cpp | 2 +- .../vector.bool/emplace_back.pass.cpp | 2 +- .../sequences/vector.bool/empty.fail.cpp | 29 - .../sequences/vector.bool/empty.verify.cpp | 27 + .../vector.bool/enabled_hash.pass.cpp | 2 +- .../sequences/vector.bool/find.pass.cpp | 2 +- .../vector.bool/get_allocator.pass.cpp | 34 + .../vector.bool/initializer_list.pass.cpp | 2 +- .../initializer_list_alloc.pass.cpp | 2 +- .../insert_iter_initializer_list.pass.cpp | 2 +- .../insert_iter_iter_iter.pass.cpp | 24 +- .../insert_iter_size_value.pass.cpp | 7 + .../vector.bool/insert_iter_value.pass.cpp | 8 + ...rator_concept_conformance.compile.pass.cpp | 54 + .../sequences/vector.bool/move.pass.cpp | 25 +- .../sequences/vector.bool/move_alloc.pass.cpp | 2 +- .../vector.bool/move_assign_noexcept.pass.cpp | 2 +- .../vector.bool/move_noexcept.pass.cpp | 2 +- .../op_equal_initializer_list.pass.cpp | 2 +- ...range_concept_conformance.compile.pass.cpp | 39 + .../reference/assign_bool.pass.cpp | 41 + .../reference/assign_copy.pass.cpp | 76 + .../vector.bool/reference/ctor_copy.pass.cpp | 33 + .../vector.bool/reference/flip.pass.cpp | 38 + .../reference/operator_bool.pass.cpp | 38 + .../reference/triviality.compile.pass.cpp | 21 + .../sequences/vector.bool/reserve.pass.cpp | 24 + .../vector.bool/resize_size.pass.cpp | 6 + .../vector.bool/swap_noexcept.pass.cpp | 2 +- .../sequences/vector/access.pass.cpp | 154 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../sequences/vector/compare.pass.cpp | 120 + .../sequences/vector/get_allocator.pass.cpp | 34 + ...rator_concept_conformance.compile.pass.cpp | 66 + ...range_concept_conformance.compile.pass.cpp | 39 + .../vector/reverse_iterators.pass.cpp | 77 + .../sequences/vector/types.pass.cpp | 3 + .../vector/vector.capacity/empty.fail.cpp | 29 - .../vector/vector.capacity/empty.verify.cpp | 27 + .../vector/vector.capacity/reserve.pass.cpp | 50 + .../vector.capacity/shrink_to_fit.pass.cpp | 2 +- .../assign_copy.addressof.compile.pass.cpp | 24 + .../vector/vector.cons/assign_copy.pass.cpp | 39 + .../assign_initializer_list.pass.cpp | 2 +- .../vector.cons/assign_iter_iter.pass.cpp | 15 +- .../assign_move.addressof.compile.pass.cpp | 24 + .../vector/vector.cons/assign_move.pass.cpp | 2 +- .../vector.cons/assign_size_value.pass.cpp | 7 +- .../vector.cons/construct_iter_iter.pass.cpp | 44 +- .../construct_iter_iter_alloc.pass.cpp | 10 +- .../vector.cons/construct_size.pass.cpp | 5 + .../vector.cons/construct_size_value.pass.cpp | 4 + .../construct_size_value_alloc.pass.cpp | 2 + .../vector.cons/copy.move_only.verify.cpp | 27 + .../vector/vector.cons/copy.pass.cpp | 12 + .../vector/vector.cons/copy_alloc.pass.cpp | 8 + .../vector/vector.cons/deduct.fail.cpp | 5 +- .../vector/vector.cons/deduct.pass.cpp | 46 +- .../vector.cons/default_noexcept.pass.cpp | 3 +- .../vector/vector.cons/dtor_noexcept.pass.cpp | 3 +- .../vector.cons/initializer_list.pass.cpp | 2 +- .../initializer_list_alloc.pass.cpp | 8 +- .../move.addressof.compile.pass.cpp | 31 + .../vector/vector.cons/move.pass.cpp | 27 +- .../vector/vector.cons/move_alloc.pass.cpp | 2 +- .../vector.cons/move_assign_noexcept.pass.cpp | 5 +- .../vector/vector.cons/move_noexcept.pass.cpp | 3 +- .../op_equal_initializer_list.pass.cpp | 2 +- .../vector/vector.erasure/erase.pass.cpp | 68 +- .../vector/vector.erasure/erase_if.pass.cpp | 63 +- .../emplace.addressof.compile.pass.cpp | 25 + .../vector/vector.modifiers/emplace.pass.cpp | 2 +- .../vector.modifiers/emplace_back.pass.cpp | 2 +- .../vector.modifiers/emplace_extra.pass.cpp | 15 +- .../erase_iter.addressof.compile.pass.cpp | 23 + .../vector.modifiers/erase_iter.pass.cpp | 15 + ...erase_iter_iter.addressof.compile.pass.cpp | 23 + .../insert_iter_initializer_list.pass.cpp | 2 +- ..._iter_iter_iter.addressof.compile.pass.cpp | 31 + .../insert_iter_iter_iter.pass.cpp | 22 +- .../insert_iter_lvalue.pass.cpp | 120 + ...ert_iter_rvalue.addressof.compile.pass.cpp | 25 + .../insert_iter_rvalue.pass.cpp | 2 +- ...iter_size_value.addressof.compile.pass.cpp | 24 + ...sert_iter_value.addressof.compile.pass.cpp | 24 + .../insert_iter_value.pass.cpp | 98 - .../push_back_rvalue.pass.cpp | 2 +- .../resize_not_move_insertable.fail.cpp | 16 +- .../swap.addressof.compile.pass.cpp | 25 + .../vector.special/swap_noexcept.pass.cpp | 4 +- ...set_allocator_requirement_test_templates.h | 55 +- test/std/containers/test_compare.h | 44 +- test/std/containers/test_hash.h | 12 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../unord/unord.map/bucket.pass.cpp | 14 +- .../unord/unord.map/bucket_size.pass.cpp | 14 +- .../unord/unord.map/compare.pass.cpp | 4 +- .../unord/unord.map/contains.pass.cpp | 3 +- .../unord.map/contains.transparent.pass.cpp | 63 + .../unord.map/count.transparent.pass.cpp | 64 + .../containers/unord/unord.map/empty.fail.cpp | 29 - .../unord/unord.map/empty.verify.cpp | 27 + .../containers/unord/unord.map/eq.pass.cpp | 75 +- .../equal_range.transparent.pass.cpp | 64 + .../unord/unord.map/erase_if.pass.cpp | 49 +- .../unord/unord.map/find.transparent.pass.cpp | 64 + .../unord/unord.map/get_allocator.pass.cpp | 38 + ...rator.operators.addressof.compile.pass.cpp | 49 + ...rator_concept_conformance.compile.pass.cpp | 68 + .../unord/unord.map/max_load_factor.pass.cpp | 15 +- ...range_concept_conformance.compile.pass.cpp | 41 + .../unord/unord.map/swap_member.pass.cpp | 48 +- .../unord.map.cnstr/allocator.pass.cpp | 32 +- .../assign_copy.addressof.compile.pass.cpp | 35 + .../unord.map.cnstr/assign_copy.pass.cpp | 48 +- .../unord.map.cnstr/assign_init.pass.cpp | 10 +- .../assign_move.addressof.compile.pass.cpp | 42 + .../unord.map.cnstr/assign_move.pass.cpp | 72 +- ...ompare_copy_constructible.compile.fail.cpp | 33 + .../compare_copy_constructible.fail.cpp | 33 - .../unord.map/unord.map.cnstr/copy.pass.cpp | 36 +- .../unord.map.cnstr/copy_alloc.pass.cpp | 36 +- .../unord.map/unord.map.cnstr/deduct.fail.cpp | 5 +- .../unord.map/unord.map.cnstr/deduct.pass.cpp | 25 +- .../unord.map.cnstr/deduct_const.pass.cpp | 3 +- .../unord.map.cnstr/default.pass.cpp | 28 +- .../unord.map.cnstr/default_noexcept.pass.cpp | 2 +- .../unord.map.cnstr/dtor_noexcept.pass.cpp | 2 +- .../hash_copy_constructible.compile.fail.cpp | 33 + .../hash_copy_constructible.fail.cpp | 33 - .../unord.map/unord.map.cnstr/init.pass.cpp | 34 +- .../unord.map.cnstr/init_size.pass.cpp | 18 +- .../unord.map.cnstr/init_size_hash.pass.cpp | 22 +- .../init_size_hash_equal.pass.cpp | 26 +- .../init_size_hash_equal_allocator.pass.cpp | 38 +- .../move.addressof.compile.pass.cpp | 33 + .../unord.map/unord.map.cnstr/move.pass.cpp | 71 +- .../move_alloc.addressof.compile.pass.cpp | 36 + .../unord.map.cnstr/move_alloc.pass.cpp | 50 +- .../move_assign_noexcept.pass.cpp | 2 +- .../unord.map.cnstr/move_noexcept.pass.cpp | 2 +- .../unord.map/unord.map.cnstr/range.pass.cpp | 32 +- .../unord.map.cnstr/range_size.pass.cpp | 20 +- .../unord.map.cnstr/range_size_hash.pass.cpp | 24 +- .../range_size_hash_equal.pass.cpp | 28 +- .../range_size_hash_equal_allocator.pass.cpp | 42 +- .../unord.map.cnstr/size.compile.fail.cpp | 71 + .../unord.map/unord.map.cnstr/size.fail.cpp | 71 - .../unord.map/unord.map.cnstr/size.pass.cpp | 16 +- .../unord.map.cnstr/size_hash.pass.cpp | 20 +- .../unord.map.cnstr/size_hash_equal.pass.cpp | 24 +- .../size_hash_equal_allocator.pass.cpp | 36 +- .../unord.map.elem/index_tuple.pass.cpp | 25 +- .../unord.map.modifiers/emplace.pass.cpp | 2 +- .../emplace_hint.addressof.compile.pass.cpp | 30 + .../unord.map.modifiers/emplace_hint.pass.cpp | 2 +- ...rase_const_iter.addressof.compile.pass.cpp | 27 + .../erase_iter_db1.pass.cpp | 42 - .../erase_iter_db2.pass.cpp | 45 - .../erase_iter_iter_db1.pass.cpp | 44 - .../erase_iter_iter_db2.pass.cpp | 44 - .../erase_iter_iter_db3.pass.cpp | 44 - .../erase_iter_iter_db4.pass.cpp | 43 - .../erase_range.addressof.compile.pass.cpp | 27 + .../extract_iterator.pass.cpp | 2 +- .../unord.map.modifiers/extract_key.pass.cpp | 2 +- ...nd_emplace_allocator_requirements.pass.cpp | 2 +- ...nt_const_lvalue.addressof.compile.pass.cpp | 28 + .../insert_hint_const_lvalue.pass.cpp | 21 +- .../insert_hint_rvalue.pass.cpp | 30 +- .../unord.map.modifiers/insert_init.pass.cpp | 2 +- .../insert_node_type.pass.cpp | 2 +- .../insert_node_type_hint.pass.cpp | 2 +- .../insert_or_assign.pass.cpp | 2 +- .../unord.map.modifiers/insert_range.pass.cpp | 4 +- .../insert_rvalue.pass.cpp | 2 +- ...ible_value_type.addressof.compile.pass.cpp | 28 + ...alue_value_type.addressof.compile.pass.cpp | 28 + .../unord.map.modifiers/merge.pass.cpp | 2 +- .../unord.map.modifiers/try.emplace.pass.cpp | 2 +- ...ry_emplace_hint.addressof.compile.pass.cpp | 40 + .../unord.map.swap/db_swap_1.pass.cpp | 47 - .../swap.addressof.compile.pass.cpp | 29 + .../unord.map.swap/swap_noexcept.pass.cpp | 2 +- .../unord.map.swap/swap_non_member.pass.cpp | 56 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../unord/unord.multimap/bucket.pass.cpp | 14 +- .../unord/unord.multimap/bucket_size.pass.cpp | 14 +- .../contains.transparent.pass.cpp | 63 + .../unord.multimap/count.transparent.pass.cpp | 64 + .../unord.multimap/db_iterators_7.pass.cpp | 62 - .../unord.multimap/db_iterators_8.pass.cpp | 58 - .../db_local_iterators_7.pass.cpp | 59 - .../db_local_iterators_8.pass.cpp | 56 - .../unord/unord.multimap/empty.fail.cpp | 29 - .../unord/unord.multimap/empty.verify.cpp | 27 + .../unord/unord.multimap/eq.pass.cpp | 81 +- .../equal_range.transparent.pass.cpp | 64 + .../unord/unord.multimap/erase_if.pass.cpp | 70 +- .../unord.multimap/find.transparent.pass.cpp | 64 + .../unord.multimap/get_allocator.pass.cpp | 38 + ...rator_concept_conformance.compile.pass.cpp | 68 + ...rs.fail.cpp => iterators.compile.fail.cpp} | 0 ...l.cpp => local_iterators.compile.fail.cpp} | 0 .../unord.multimap/max_load_factor.pass.cpp | 14 +- ...range_concept_conformance.compile.pass.cpp | 41 + .../unord/unord.multimap/swap_member.pass.cpp | 48 +- .../unord.multimap.cnstr/allocator.pass.cpp | 32 +- .../assign_copy.addressof.compile.pass.cpp | 35 + .../unord.multimap.cnstr/assign_copy.pass.cpp | 48 +- .../unord.multimap.cnstr/assign_init.pass.cpp | 10 +- .../unord.multimap.cnstr/assign_move.pass.cpp | 56 +- ...ompare_copy_constructible.compile.fail.cpp | 33 + .../compare_copy_constructible.fail.cpp | 33 - .../unord.multimap.cnstr/copy.pass.cpp | 36 +- .../unord.multimap.cnstr/copy_alloc.pass.cpp | 36 +- .../unord.multimap.cnstr/deduct.fail.cpp | 5 +- .../unord.multimap.cnstr/deduct.pass.cpp | 25 +- .../deduct_const.pass.cpp | 3 +- .../unord.multimap.cnstr/default.pass.cpp | 28 +- .../default_noexcept.pass.cpp | 2 +- .../dtor_noexcept.pass.cpp | 2 +- .../hash_copy_constructible.compile.fail.cpp | 33 + .../hash_copy_constructible.fail.cpp | 33 - .../unord.multimap.cnstr/init.pass.cpp | 26 +- .../unord.multimap.cnstr/init_size.pass.cpp | 18 +- .../init_size_hash.pass.cpp | 22 +- .../init_size_hash_equal.pass.cpp | 26 +- .../init_size_hash_equal_allocator.pass.cpp | 38 +- .../move.addressof.compile.pass.cpp | 33 + .../unord.multimap.cnstr/move.pass.cpp | 67 +- .../move_alloc.addressof.compile.pass.cpp | 36 + .../unord.multimap.cnstr/move_alloc.pass.cpp | 54 +- .../move_assign_noexcept.pass.cpp | 2 +- .../move_noexcept.pass.cpp | 2 +- .../unord.multimap.cnstr/range.pass.cpp | 32 +- .../unord.multimap.cnstr/range_size.pass.cpp | 20 +- .../range_size_hash.pass.cpp | 24 +- .../range_size_hash_equal.pass.cpp | 28 +- .../range_size_hash_equal_allocator.pass.cpp | 42 +- .../size.compile.fail.cpp | 71 + .../unord.multimap.cnstr/size.fail.cpp | 71 - .../unord.multimap.cnstr/size.pass.cpp | 16 +- .../unord.multimap.cnstr/size_hash.pass.cpp | 20 +- .../size_hash_equal.pass.cpp | 24 +- .../size_hash_equal_allocator.pass.cpp | 36 +- .../unord.multimap.modifiers/emplace.pass.cpp | 2 +- .../emplace_hint.addressof.compile.pass.cpp | 30 + .../emplace_hint.pass.cpp | 2 +- .../erase_iter_db1.pass.cpp | 42 - .../erase_iter_db2.pass.cpp | 45 - .../erase_iter_iter_db1.pass.cpp | 44 - .../erase_iter_iter_db2.pass.cpp | 44 - .../erase_iter_iter_db3.pass.cpp | 44 - .../erase_iter_iter_db4.pass.cpp | 43 - .../extract_iterator.pass.cpp | 2 +- .../extract_key.pass.cpp | 2 +- .../insert_allocator_requirements.pass.cpp | 2 +- .../insert_hint_const_lvalue.pass.cpp | 21 +- .../insert_hint_rvalue.pass.cpp | 20 +- .../insert_init.pass.cpp | 2 +- .../insert_node_type.pass.cpp | 2 +- .../insert_node_type_hint.pass.cpp | 2 +- .../insert_range.pass.cpp | 4 +- .../insert_rvalue.pass.cpp | 2 +- .../unord.multimap.modifiers/merge.pass.cpp | 2 +- .../unord.multimap.swap/db_swap_1.pass.cpp | 47 - .../swap_noexcept.pass.cpp | 2 +- .../swap_non_member.pass.cpp | 56 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../unord/unord.multiset/bucket.pass.cpp | 14 +- .../unord/unord.multiset/bucket_size.pass.cpp | 15 +- .../contains.transparent.pass.cpp | 63 + .../unord.multiset/count.transparent.pass.cpp | 64 + .../unord.multiset/db_iterators_7.pass.cpp | 60 - .../unord.multiset/db_iterators_8.pass.cpp | 56 - .../db_local_iterators_7.pass.cpp | 59 - .../db_local_iterators_8.pass.cpp | 56 - .../unord/unord.multiset/emplace.pass.cpp | 2 +- .../unord.multiset/emplace_hint.pass.cpp | 2 +- .../unord/unord.multiset/empty.fail.cpp | 29 - .../unord/unord.multiset/empty.verify.cpp | 27 + .../equal_range.transparent.pass.cpp | 64 + .../unord/unord.multiset/erase_if.pass.cpp | 68 +- .../unord.multiset/erase_iter_db1.pass.cpp | 41 - .../unord.multiset/erase_iter_db2.pass.cpp | 44 - .../erase_iter_iter_db1.pass.cpp | 43 - .../erase_iter_iter_db2.pass.cpp | 43 - .../erase_iter_iter_db3.pass.cpp | 43 - .../erase_iter_iter_db4.pass.cpp | 42 - .../unord.multiset/extract_iterator.pass.cpp | 2 +- .../unord/unord.multiset/extract_key.pass.cpp | 2 +- .../unord.multiset/find.transparent.pass.cpp | 64 + .../unord.multiset/get_allocator.pass.cpp | 36 + ...rt_emplace_allocator_requirements.pass.cpp | 2 +- .../insert_hint_const_lvalue.pass.cpp | 21 +- .../unord/unord.multiset/insert_init.pass.cpp | 2 +- .../unord.multiset/insert_node_type.pass.cpp | 2 +- .../insert_node_type_hint.pass.cpp | 2 +- .../unord.multiset/insert_range.pass.cpp | 4 +- .../unord.multiset/insert_rvalue.pass.cpp | 2 +- ...rator_concept_conformance.compile.pass.cpp | 68 + ...rs.fail.cpp => iterators.compile.fail.cpp} | 0 ...l.cpp => local_iterators.compile.fail.cpp} | 0 .../unord.multiset/max_load_factor.pass.cpp | 14 +- .../unord/unord.multiset/merge.pass.cpp | 2 +- ...range_concept_conformance.compile.pass.cpp | 41 + .../unord/unord.multiset/swap_member.pass.cpp | 48 +- .../unord.multiset.cnstr/allocator.pass.cpp | 24 +- .../assign_copy.addressof.compile.pass.cpp | 28 + .../unord.multiset.cnstr/assign_copy.pass.cpp | 48 +- .../unord.multiset.cnstr/assign_init.pass.cpp | 10 +- .../unord.multiset.cnstr/assign_move.pass.cpp | 90 +- ...ompare_copy_constructible.compile.fail.cpp | 31 + .../compare_copy_constructible.fail.cpp | 30 - .../unord.multiset.cnstr/copy.pass.cpp | 36 +- .../unord.multiset.cnstr/copy_alloc.pass.cpp | 24 +- .../unord.multiset.cnstr/deduct.fail.cpp | 5 +- .../unord.multiset.cnstr/deduct.pass.cpp | 8 +- .../unord.multiset.cnstr/default.pass.cpp | 28 +- .../default_noexcept.pass.cpp | 2 +- .../dtor_noexcept.pass.cpp | 2 +- .../hash_copy_constructible.compile.fail.cpp | 31 + .../hash_copy_constructible.fail.cpp | 30 - .../unord.multiset.cnstr/init.pass.cpp | 26 +- .../unord.multiset.cnstr/init_size.pass.cpp | 18 +- .../init_size_hash.pass.cpp | 22 +- .../init_size_hash_equal.pass.cpp | 26 +- .../init_size_hash_equal_allocator.pass.cpp | 26 +- .../move.addressof.compile.pass.cpp | 29 + .../unord.multiset.cnstr/move.pass.cpp | 67 +- .../move_alloc.addressof.compile.pass.cpp | 33 + .../unord.multiset.cnstr/move_alloc.pass.cpp | 50 +- .../move_assign_noexcept.pass.cpp | 2 +- .../move_noexcept.pass.cpp | 2 +- .../unord.multiset.cnstr/range.pass.cpp | 32 +- .../unord.multiset.cnstr/range_size.pass.cpp | 20 +- .../range_size_hash.pass.cpp | 24 +- .../range_size_hash_equal.pass.cpp | 28 +- .../range_size_hash_equal_allocator.pass.cpp | 28 +- .../size.compile.fail.cpp | 67 + .../unord.multiset.cnstr/size.fail.cpp | 67 - .../unord.multiset.cnstr/size.pass.cpp | 16 +- .../unord.multiset.cnstr/size_hash.pass.cpp | 20 +- .../size_hash_equal.pass.cpp | 24 +- .../size_hash_equal_allocator.pass.cpp | 24 +- .../unord.multiset.swap/db_swap_1.pass.cpp | 46 - .../swap_noexcept.pass.cpp | 2 +- .../swap_non_member.pass.cpp | 56 +- ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../unord/unord.set/bucket.pass.cpp | 14 +- .../unord/unord.set/bucket_size.pass.cpp | 14 +- .../unord/unord.set/contains.pass.cpp | 3 +- .../unord.set/contains.transparent.pass.cpp | 63 + .../unord.set/count.transparent.pass.cpp | 64 + .../unord/unord.set/db_iterators_7.pass.cpp | 60 - .../unord/unord.set/db_iterators_8.pass.cpp | 56 - .../unord.set/db_local_iterators_7.pass.cpp | 59 - .../unord.set/db_local_iterators_8.pass.cpp | 57 - .../unord/unord.set/emplace.pass.cpp | 2 +- .../emplace_hint.addressof.compile.pass.cpp | 30 + .../unord/unord.set/emplace_hint.pass.cpp | 2 +- .../containers/unord/unord.set/empty.fail.cpp | 29 - .../unord/unord.set/empty.verify.cpp | 27 + .../equal_range.transparent.pass.cpp | 64 + .../unord/unord.set/erase_if.pass.cpp | 47 +- .../unord/unord.set/erase_iter_db1.pass.cpp | 41 - .../unord/unord.set/erase_iter_db2.pass.cpp | 44 - .../unord.set/erase_iter_iter_db1.pass.cpp | 43 - .../unord.set/erase_iter_iter_db2.pass.cpp | 43 - .../unord.set/erase_iter_iter_db3.pass.cpp | 43 - .../unord.set/erase_iter_iter_db4.pass.cpp | 42 - .../unord/unord.set/extract_iterator.pass.cpp | 2 +- .../unord/unord.set/extract_key.pass.cpp | 2 +- .../unord/unord.set/find.transparent.pass.cpp | 64 + .../unord/unord.set/get_allocator.pass.cpp | 36 + ...nd_emplace_allocator_requirements.pass.cpp | 2 +- ...nt_const_lvalue.addressof.compile.pass.cpp | 28 + .../insert_hint_const_lvalue.pass.cpp | 25 +- ...ert_hint_rvalue.addressof.compile.pass.cpp | 27 + .../unord.set/insert_hint_rvalue.pass.cpp | 12 +- .../unord/unord.set/insert_init.pass.cpp | 2 +- .../unord/unord.set/insert_node_type.pass.cpp | 2 +- .../unord.set/insert_node_type_hint.pass.cpp | 2 +- .../unord/unord.set/insert_range.pass.cpp | 4 +- ...rator.operators.addressof.compile.pass.cpp | 47 + ...rator_concept_conformance.compile.pass.cpp | 67 + ...rs.fail.cpp => iterators.compile.fail.cpp} | 0 ...l.cpp => local_iterators.compile.fail.cpp} | 0 .../unord/unord.set/max_load_factor.pass.cpp | 14 +- .../containers/unord/unord.set/merge.pass.cpp | 2 +- ...range_concept_conformance.compile.pass.cpp | 41 + .../unord/unord.set/swap_member.pass.cpp | 48 +- .../unord.set.cnstr/allocator.pass.cpp | 24 +- .../assign_copy.addressof.compile.pass.cpp | 28 + .../unord.set.cnstr/assign_copy.pass.cpp | 48 +- .../unord.set.cnstr/assign_init.pass.cpp | 10 +- .../unord.set.cnstr/assign_move.pass.cpp | 72 +- ...ompare_copy_constructible.compile.fail.cpp | 31 + .../compare_copy_constructible.fail.cpp | 30 - .../unord.set/unord.set.cnstr/copy.pass.cpp | 36 +- .../unord.set.cnstr/copy_alloc.pass.cpp | 24 +- .../unord.set/unord.set.cnstr/deduct.fail.cpp | 5 +- .../unord.set/unord.set.cnstr/deduct.pass.cpp | 8 +- .../unord.set.cnstr/default.pass.cpp | 28 +- .../unord.set.cnstr/default_noexcept.pass.cpp | 2 +- .../unord.set.cnstr/dtor_noexcept.pass.cpp | 2 +- .../hash_copy_constructible.compile.fail.cpp | 31 + .../hash_copy_constructible.fail.cpp | 30 - .../unord.set/unord.set.cnstr/init.pass.cpp | 26 +- .../unord.set.cnstr/init_size.pass.cpp | 18 +- .../unord.set.cnstr/init_size_hash.pass.cpp | 22 +- .../init_size_hash_equal.pass.cpp | 26 +- .../init_size_hash_equal_allocator.pass.cpp | 26 +- .../move.addressof.compile.pass.cpp | 29 + .../unord.set/unord.set.cnstr/move.pass.cpp | 67 +- .../move_alloc.addressof.compile.pass.cpp | 35 + .../unord.set.cnstr/move_alloc.pass.cpp | 38 +- .../move_assign_noexcept.pass.cpp | 2 +- .../unord.set.cnstr/move_noexcept.pass.cpp | 2 +- .../unord.set/unord.set.cnstr/range.pass.cpp | 32 +- .../unord.set.cnstr/range_size.pass.cpp | 20 +- .../unord.set.cnstr/range_size_hash.pass.cpp | 24 +- .../range_size_hash_equal.pass.cpp | 28 +- .../range_size_hash_equal_allocator.pass.cpp | 28 +- .../unord.set.cnstr/size.compile.fail.cpp | 47 + .../unord.set/unord.set.cnstr/size.fail.cpp | 47 - .../unord.set/unord.set.cnstr/size.pass.cpp | 16 +- .../unord.set.cnstr/size_hash.pass.cpp | 20 +- .../unord.set.cnstr/size_hash_equal.pass.cpp | 24 +- .../size_hash_equal_allocator.pass.cpp | 24 +- .../unord.set.swap/db_swap_1.pass.cpp | 46 - .../unord.set.swap/swap_noexcept.pass.cpp | 2 +- .../unord.set.swap/swap_non_member.pass.cpp | 56 +- .../enable_borrowed_range.compile.pass.cpp | 28 + ...range_concept_conformance.compile.pass.cpp | 39 + .../containers/views/span.cons/array.fail.cpp | 7 +- .../containers/views/span.cons/array.pass.cpp | 73 +- .../views/span.cons/assign.pass.cpp | 47 +- .../views/span.cons/container.fail.cpp | 117 - .../views/span.cons/container.pass.cpp | 113 - .../containers/views/span.cons/copy.pass.cpp | 10 +- .../views/span.cons/deduct.pass.cpp | 96 +- .../views/span.cons/default.fail.cpp | 14 +- .../views/span.cons/default.pass.cpp | 14 +- .../views/span.cons/initializer_list.pass.cpp | 46 + .../views/span.cons/iterator_len.pass.cpp | 71 + .../views/span.cons/iterator_len.verify.cpp | 39 + .../span.cons/iterator_sentinel.pass.cpp | 66 + .../span.cons/iterator_sentinel.verify.cpp | 36 + .../views/span.cons/ptr_len.fail.cpp | 64 - .../views/span.cons/ptr_len.pass.cpp | 114 - .../views/span.cons/ptr_ptr.fail.cpp | 64 - .../views/span.cons/ptr_ptr.pass.cpp | 114 - .../containers/views/span.cons/range.pass.cpp | 86 + .../span.cons/span.dtor.compile.pass.cpp | 26 + .../containers/views/span.cons/span.fail.cpp | 17 +- .../containers/views/span.cons/span.pass.cpp | 37 +- .../views/span.cons/stdarray.pass.cpp | 83 +- .../containers/views/span.elem/back.pass.cpp | 20 +- .../containers/views/span.elem/data.pass.cpp | 10 +- .../containers/views/span.elem/front.pass.cpp | 19 +- .../views/span.elem/op_idx.pass.cpp | 14 +- .../views/span.iterators/begin.pass.cpp | 31 +- .../views/span.iterators/end.pass.cpp | 41 +- ...rator_concept_conformance.compile.pass.cpp | 30 + .../views/span.iterators/rbegin.pass.cpp | 33 +- .../views/span.iterators/rend.pass.cpp | 33 +- .../views/span.objectrep/as_bytes.pass.cpp | 12 +- .../span.objectrep/as_writable_bytes.fail.cpp | 10 +- .../span.objectrep/as_writable_bytes.pass.cpp | 12 +- .../views/span.obs/empty.nodiscard.verify.cpp | 23 + .../containers/views/span.obs/empty.pass.cpp | 12 +- .../containers/views/span.obs/size.pass.cpp | 12 +- .../views/span.obs/size_bytes.pass.cpp | 12 +- .../containers/views/span.sub/first.fail.cpp | 44 + .../containers/views/span.sub/first.pass.cpp | 14 +- .../containers/views/span.sub/last.fail.cpp | 44 + .../containers/views/span.sub/last.pass.cpp | 14 +- .../views/span.sub/subspan.fail.cpp | 56 + .../views/span.sub/subspan.pass.cpp | 16 +- .../containers/views/span.tuple/get.fail.cpp | 29 - .../containers/views/span.tuple/get.pass.cpp | 75 - .../views/span.tuple/tuple_element.fail.cpp | 27 - .../views/span.tuple/tuple_element.pass.cpp | 52 - .../views/span.tuple/tuple_size.fail.cpp | 21 - .../views/span.tuple/tuple_size.pass.cpp | 46 - .../views/trivially_copyable.compile.pass.cpp | 18 + test/std/containers/views/types.pass.cpp | 29 +- .../atomic_init.depr_in_cxx20.verify.cpp | 23 + test/std/depr/depr.auto.ptr/auto.ptr/A.h | 4 +- test/std/depr/depr.auto.ptr/auto.ptr/AB.h | 4 +- ...t.fail.cpp => assignment.compile.fail.cpp} | 0 .../auto.ptr.cons/assignment.pass.cpp | 2 +- ...vert.fail.cpp => convert.compile.fail.cpp} | 0 .../auto.ptr/auto.ptr.cons/convert.pass.cpp | 2 +- ...pp => convert_assignment.compile.fail.cpp} | 0 .../auto.ptr.cons/convert_assignment.pass.cpp | 2 +- .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../auto.ptr/auto.ptr.cons/copy.pass.cpp | 2 +- ...cit.fail.cpp => explicit.compile.fail.cpp} | 0 .../auto.ptr/auto.ptr.cons/pointer.pass.cpp | 2 +- .../assign_from_auto_ptr_ref.pass.cpp | 2 +- .../convert_from_auto_ptr_ref.pass.cpp | 2 +- .../convert_to_auto_ptr.pass.cpp | 2 +- .../convert_to_auto_ptr_ref.pass.cpp | 2 +- .../auto.ptr/auto.ptr.members/arrow.pass.cpp | 2 +- .../auto.ptr/auto.ptr.members/deref.pass.cpp | 2 +- .../auto.ptr.members/release.pass.cpp | 2 +- .../auto.ptr/auto.ptr.members/reset.pass.cpp | 2 +- .../auto.ptr/element_type.pass.cpp | 2 +- .../depr/depr.auto.ptr/nothing_to_do.pass.cpp | 13 - test/std/depr/depr.c.headers/errno_h.pass.cpp | 1 - test/std/depr/depr.c.headers/fenv_h.pass.cpp | 2 - test/std/depr/depr.c.headers/float_h.pass.cpp | 8 +- .../depr/depr.c.headers/inttypes_h.pass.cpp | 2 + .../std/depr/depr.c.headers/locale_h.pass.cpp | 4 +- test/std/depr/depr.c.headers/math_h.pass.cpp | 2 + .../std/depr/depr.c.headers/stddef_h.pass.cpp | 2 + .../std/depr/depr.c.headers/stdint_h.pass.cpp | 7 +- test/std/depr/depr.c.headers/stdint_h.sh.cpp | 268 - test/std/depr/depr.c.headers/stdio_h.pass.cpp | 4 + .../stdlib_h.aligned_alloc.compile.pass.cpp | 24 + .../std/depr/depr.c.headers/stdlib_h.pass.cpp | 16 +- .../std/depr/depr.c.headers/string_h.pass.cpp | 64 +- test/std/depr/depr.c.headers/uchar_h.pass.cpp | 4 +- test/std/depr/depr.c.headers/wchar_h.pass.cpp | 148 +- .../std/depr/depr.c.headers/wctype_h.pass.cpp | 2 + ..._to_binary_function.cxx1z.compile.fail.cpp | 28 + .../pointer_to_binary_function.cxx1z.fail.cpp | 28 - .../pointer_to_binary_function.pass.cpp | 2 +- ...r_to_unary_function.cxx1z.compile.fail.cpp | 28 + .../pointer_to_unary_function.cxx1z.fail.cpp | 28 - .../pointer_to_unary_function.pass.cpp | 2 +- .../ptr_fun1.cxx1z.compile.fail.cpp | 31 + .../ptr_fun1.cxx1z.fail.cpp | 31 - .../ptr_fun1.pass.cpp | 2 +- .../ptr_fun2.cxx1z.compile.fail.cpp | 31 + .../ptr_fun2.cxx1z.fail.cpp | 31 - .../ptr_fun2.pass.cpp | 2 +- .../const_mem_fun.cxx1z.compile.fail.cpp | 38 + .../const_mem_fun.cxx1z.fail.cpp | 38 - .../const_mem_fun.pass.cpp | 2 +- .../const_mem_fun1.cxx1z.compile.fail.cpp | 38 + .../const_mem_fun1.cxx1z.fail.cpp | 38 - .../const_mem_fun1.pass.cpp | 2 +- ...onst_mem_fun1_ref_t.cxx1z.compile.fail.cpp | 36 + .../const_mem_fun1_ref_t.cxx1z.fail.cpp | 36 - .../const_mem_fun1_ref_t.pass.cpp | 2 +- .../const_mem_fun1_t.cxx1z.compile.fail.cpp | 36 + .../const_mem_fun1_t.cxx1z.fail.cpp | 36 - .../const_mem_fun1_t.pass.cpp | 2 +- .../const_mem_fun_ref.cxx1z.compile.fail.cpp | 38 + .../const_mem_fun_ref.cxx1z.fail.cpp | 38 - .../const_mem_fun_ref.pass.cpp | 2 +- .../const_mem_fun_ref1.cxx1z.compile.fail.cpp | 38 + .../const_mem_fun_ref1.cxx1z.fail.cpp | 38 - .../const_mem_fun_ref1.pass.cpp | 2 +- ...const_mem_fun_ref_t.cxx1z.compile.fail.cpp | 36 + .../const_mem_fun_ref_t.cxx1z.fail.cpp | 36 - .../const_mem_fun_ref_t.pass.cpp | 2 +- .../const_mem_fun_t.cxx1z.compile.fail.cpp | 36 + .../const_mem_fun_t.cxx1z.fail.cpp | 36 - .../const_mem_fun_t.pass.cpp | 2 +- .../mem_fun.cxx1z.compile.fail.cpp | 38 + .../mem_fun.cxx1z.fail.cpp | 38 - .../mem_fun.pass.cpp | 2 +- .../mem_fun1.cxx1z.compile.fail.cpp | 38 + .../mem_fun1.cxx1z.fail.cpp | 38 - .../mem_fun1.pass.cpp | 2 +- .../mem_fun1_ref_t.cxx1z.compile.fail.cpp | 36 + .../mem_fun1_ref_t.cxx1z.fail.cpp | 36 - .../mem_fun1_ref_t.pass.cpp | 2 +- .../mem_fun1_t.cxx1z.compile.fail.cpp | 36 + .../mem_fun1_t.cxx1z.fail.cpp | 36 - .../mem_fun1_t.pass.cpp | 2 +- .../mem_fun_ref.cxx1z.compile.fail.cpp | 38 + .../mem_fun_ref.cxx1z.fail.cpp | 38 - .../mem_fun_ref.pass.cpp | 2 +- .../mem_fun_ref1.cxx1z.compile.fail.cpp | 38 + .../mem_fun_ref1.cxx1z.fail.cpp | 38 - .../mem_fun_ref1.pass.cpp | 2 +- .../mem_fun_ref_t.cxx1z.compile.fail.cpp | 36 + .../mem_fun_ref_t.cxx1z.fail.cpp | 36 - .../mem_fun_ref_t.pass.cpp | 2 +- .../mem_fun_t.cxx1z.compile.fail.cpp | 36 + .../mem_fun_t.cxx1z.fail.cpp | 36 - .../mem_fun_t.pass.cpp | 2 +- .../depr.adaptors/nothing_to_do.pass.cpp | 13 - .../depr.base/binary_function.pass.cpp | 2 +- .../depr.base/unary_function.pass.cpp | 2 +- .../nothing_to_do.pass.cpp | 13 - test/std/depr/depr.ios.members/lit.local.cfg | 2 + .../bind1st.depr_in_cxx11.fail.cpp | 30 - .../bind1st.depr_in_cxx11.verify.cpp | 26 + .../depr.lib.bind.1st/bind1st.pass.cpp | 2 +- .../bind2nd.depr_in_cxx11.fail.cpp | 30 - .../bind2nd.depr_in_cxx11.verify.cpp | 26 + .../depr.lib.bind.2nd/bind2nd.pass.cpp | 2 +- .../binder1st.depr_in_cxx11.fail.cpp | 30 - .../binder1st.depr_in_cxx11.verify.cpp | 26 + .../depr.lib.binder.1st/binder1st.pass.cpp | 2 +- .../binder2nd.depr_in_cxx11.fail.cpp | 30 - .../binder2nd.depr_in_cxx11.verify.cpp | 26 + .../depr.lib.binder.2nd/binder2nd.pass.cpp | 2 +- .../depr.lib.binders/nothing_to_do.pass.cpp | 13 - test/std/depr/depr.lib.binders/test_func.h | 2 +- .../depr.strstreambuf.cons/default.pass.cpp | 19 +- .../overflow.pass.cpp | 4 - .../depr/depr.str.strstreams/lit.local.cfg | 2 + .../nothing_to_do.pass.cpp | 13 - .../set.unexpected/get_unexpected.pass.cpp | 2 +- .../set.unexpected/set_unexpected.pass.cpp | 2 +- .../unexpected_handler.pass.cpp | 2 +- .../unexpected/unexpected.pass.cpp | 2 +- test/std/depr/nothing_to_do.pass.cpp | 13 - test/std/diagnostics/errno/cerrno.pass.cpp | 1 - test/std/diagnostics/nothing_to_do.pass.cpp | 13 - .../syserr/is_error_code_enum.pass.cpp | 1 + .../syserr/is_error_condition_enum.pass.cpp | 3 +- .../syserr.errcat/nothing_to_do.pass.cpp | 13 - .../default_ctor.pass.cpp | 2 +- .../generic_category.pass.cpp | 11 +- .../system_category.pass.cpp | 11 +- .../syserr.errcode/nothing_to_do.pass.cpp | 13 - .../stream_inserter.pass.cpp | 2 + .../syserr.errcode.observers/bool.fail.cpp | 29 - .../syserr.errcode.observers/bool.pass.cpp | 6 +- .../nothing_to_do.pass.cpp | 13 - .../syserr/syserr.hash/enabled_hash.pass.cpp | 2 +- .../syserr.syserr/nothing_to_do.pass.cpp | 13 - .../ctor_error_code.pass.cpp | 5 +- ...tor_error_code_const_char_pointer.pass.cpp | 5 +- .../ctor_error_code_string.pass.cpp | 5 +- .../ctor_int_error_category.pass.cpp | 5 +- ...error_category_const_char_pointer.pass.cpp | 5 +- .../ctor_int_error_category_string.pass.cpp | 5 +- .../algorithms/alg.search/search.pass.cpp | 2 +- .../fs.req.macros/feature_macro.pass.cpp | 4 +- .../fs.req.namespace/namespace.pass.cpp | 3 +- .../std/experimental/filesystem/lit.local.cfg | 2 +- .../default.pass.cpp | 2 +- .../func.searchers.boyer_moore/hash.pass.cpp | 2 +- .../hash.pred.pass.cpp | 2 +- .../func.searchers.boyer_moore/pred.pass.cpp | 2 +- .../default.pass.cpp | 2 +- .../hash.pass.cpp | 2 +- .../hash.pred.pass.cpp | 2 +- .../pred.pass.cpp | 2 +- .../func.searchers.default/default.pass.cpp | 2 +- .../default.pred.pass.cpp | 2 +- .../make_default_searcher.pass.cpp | 2 +- .../make_default_searcher.pred.pass.cpp | 2 +- .../func.searchers/nothing_to_do.pass.cpp | 14 - .../header.functional.synop/includes.pass.cpp | 2 +- .../experimental/func/nothing_to_do.pass.cpp | 14 - .../iterator/nothing_to_do.pass.cpp | 15 - .../ostream_joiner.cons.pass.cpp | 20 +- .../make_ostream_joiner.pass.cpp | 5 +- .../ostream_joiner.op.assign.pass.cpp | 18 +- .../ostream_joiner.op.postincrement.pass.cpp | 9 +- .../ostream_joiner.op.pretincrement.pass.cpp | 9 +- .../ostream_joiner.op.star.pass.cpp | 9 +- .../operator_bool.pass.cpp | 3 +- .../equal_comp.pass.cpp | 3 +- .../less_comp.pass.cpp | 3 +- .../coroutine.handle.completion/done.pass.cpp | 3 +- .../coroutine.handle.con/assign.pass.cpp | 3 +- .../coroutine.handle.con/construct.pass.cpp | 3 +- .../coroutine.handle.export/address.pass.cpp | 3 +- .../from_address.fail.cpp | 3 +- .../from_address.pass.cpp | 3 +- .../coroutine.handle.hash/hash.pass.cpp | 3 +- .../noop_coroutine.pass.cpp | 7 +- .../coroutine.handle.prom/promise.pass.cpp | 5 +- .../destroy.pass.cpp | 3 +- .../resume.pass.cpp | 3 +- .../coroutine.handle/void_handle.pass.cpp | 3 +- .../coroutine.traits/promise_type.pass.cpp | 3 +- .../suspend_always.pass.cpp | 3 +- .../suspend_never.pass.cpp | 3 +- .../end.to.end/await_result.pass.cpp | 5 +- .../end.to.end/bool_await_suspend.pass.cpp | 7 +- .../end.to.end/expected.pass.cpp | 42 +- .../end.to.end/fullexpr-dtor.pass.cpp | 5 +- .../end.to.end/generator.pass.cpp | 76 +- .../support.coroutines/end.to.end/go.pass.cpp | 7 +- .../end.to.end/multishot_func.pass.cpp | 5 +- .../end.to.end/oneshot_func.pass.cpp | 5 +- .../support.coroutines/includes.pass.cpp | 3 +- .../support.coroutines/lit.local.cfg | 5 +- .../assign.pass.cpp | 2 +- .../copy.pass.cpp | 2 +- .../default.pass.cpp | 2 +- .../memory_resource_convert.pass.cpp | 2 +- .../other_alloc.pass.cpp | 2 +- .../equal.pass.cpp | 2 +- .../not_equal.pass.cpp | 2 +- .../allocate.pass.cpp | 8 +- .../construct_pair.pass.cpp | 2 +- .../construct_pair_const_lvalue_pair.pass.cpp | 2 +- .../construct_pair_rvalue.pass.cpp | 2 +- .../construct_pair_values.pass.cpp | 2 +- .../construct_piecewise_pair.pass.cpp | 2 +- .../construct_piecewise_pair_evil.pass.cpp | 2 +- .../construct_types.pass.cpp | 2 +- .../deallocate.pass.cpp | 2 +- .../destroy.pass.cpp | 2 +- .../resource.pass.cpp | 2 +- ...ct_on_container_copy_construction.pass.cpp | 2 +- .../nothing_to_do.pass.cpp | 11 - .../alloc_copy.pass.cpp | 2 +- .../alloc_move.pass.cpp | 2 +- .../default.pass.cpp | 2 +- .../do_allocate_and_deallocate.pass.cpp | 9 +- .../do_is_equal.pass.cpp | 2 +- .../overview.pass.cpp | 4 +- .../header_deque_synop.pass.cpp | 3 +- .../header_forward_list_synop.pass.cpp | 3 +- .../header_list_synop.pass.cpp | 3 +- .../header_map_synop.pass.cpp | 3 +- .../header_regex_synop.pass.cpp | 8 +- .../header_set_synop.pass.cpp | 3 +- .../header_string_synop.pass.cpp | 7 +- .../header_unordered_map_synop.pass.cpp | 3 +- .../header_unordered_set_synop.pass.cpp | 3 +- .../header_vector_synop.pass.cpp | 3 +- .../default_resource.pass.cpp | 2 +- .../new_delete_resource.pass.cpp | 14 +- .../null_memory_resource.pass.cpp | 14 +- .../nothing_to_do.pass.cpp | 1 - .../memory/memory.resource/construct.fail.cpp | 2 +- .../memory.resource.eq/equal.pass.cpp | 2 +- .../memory.resource.eq/not_equal.pass.cpp | 2 +- .../private_members.fail.cpp | 28 + .../protected_members.fail.cpp | 28 - .../memory.resource.public/allocate.pass.cpp | 2 +- .../deallocate.pass.cpp | 2 +- .../memory.resource.public/dtor.pass.cpp | 2 +- .../memory.resource.public/is_equal.pass.cpp | 2 +- .../memory/nothing_to_do.pass.cpp | 14 - test/std/experimental/nothing_to_do.pass.cpp | 11 - .../simd/simd.abi/vector_extension.pass.cpp | 2 +- .../simd/simd.access/default.pass.cpp | 26 +- .../simd/simd.casts/simd_cast.pass.cpp | 2 +- .../simd/simd.casts/static_simd_cast.pass.cpp | 2 +- .../simd/simd.cons/broadcast.pass.cpp | 2 +- .../simd/simd.cons/default.pass.cpp | 2 +- .../simd/simd.cons/generator.pass.cpp | 2 +- .../experimental/simd/simd.cons/load.pass.cpp | 2 +- .../experimental/simd/simd.mem/load.pass.cpp | 2 +- .../experimental/simd/simd.mem/store.pass.cpp | 2 +- .../simd/simd.traits/abi_for_size.pass.cpp | 2 +- .../simd/simd.traits/is_abi_tag.pass.cpp | 2 +- .../simd/simd.traits/is_simd.pass.cpp | 2 +- .../simd.traits/is_simd_flag_type.pass.cpp | 2 +- .../simd/simd.traits/is_simd_mask.pass.cpp | 2 +- .../meta/meta.detect/detected_or.pass.cpp | 2 +- .../meta/meta.detect/detected_t.pass.cpp | 2 +- .../meta/meta.detect/is_detected.pass.cpp | 2 +- .../is_detected_convertible.pass.cpp | 2 +- .../meta.detect/is_detected_exact.pass.cpp | 2 +- .../meta/meta.detect/nonesuch.fail.cpp | 6 +- .../meta/meta.detect/nonesuch.pass.cpp | 2 +- .../utilities/nothing_to_do.pass.cpp | 14 - .../assign.pass.cpp | 4 +- .../assign_convertible_element_type.pass.cpp | 2 +- ...ssign_convertible_propagate_const.pass.cpp | 4 +- .../assign_element_type.pass.cpp | 2 +- .../move_assign.pass.cpp | 2 +- .../move_assign_convertible.pass.cpp | 2 +- ...ssign_convertible_propagate_const.pass.cpp | 2 +- ...rtible_element_type.explicit.ctor.pass.cpp | 3 +- ...le_element_type.non-explicit.ctor.pass.cpp | 3 +- ...ertible_propagate_const.copy_ctor.pass.cpp | 5 +- ...ropagate_const.explicit.move_ctor.pass.cpp | 2 +- ...ertible_propagate_const.move_ctor.pass.cpp | 3 +- .../propagate_const.ctors/copy_ctor.pass.cpp | 4 +- .../element_type.explicit.ctor.pass.cpp | 3 +- .../element_type.non-explicit.ctor.pass.cpp | 4 +- .../propagate_const.ctors/move_ctor.pass.cpp | 2 +- .../dereference.pass.cpp | 2 +- ...xplicit_operator_element_type_ptr.pass.cpp | 4 +- .../get.pass.cpp | 2 +- .../op_arrow.pass.cpp | 2 +- .../operator_element_type_ptr.pass.cpp | 2 +- .../dereference.pass.cpp | 2 +- ...xplicit_operator_element_type_ptr.pass.cpp | 2 +- .../propagate_const.observers/get.pass.cpp | 2 +- .../op_arrow.pass.cpp | 2 +- .../operator_element_type_ptr.pass.cpp | 4 +- .../propagate_const.class/swap.pass.cpp | 3 +- .../propagate_const.nonmembers/hash.pass.cpp | 2 +- .../equal_to.pass.cpp | 2 +- .../greater.pass.cpp | 2 +- .../greater_equal.pass.cpp | 2 +- .../less.pass.cpp | 2 +- .../less_equal.pass.cpp | 2 +- .../not_equal_to.pass.cpp | 2 +- .../propagate_const.relops/equal.pass.cpp | 2 +- .../greater_equal.pass.cpp | 2 +- .../greater_than.pass.cpp | 2 +- .../less_equal.pass.cpp | 2 +- .../propagate_const.relops/less_than.pass.cpp | 2 +- .../propagate_const.relops/not_equal.pass.cpp | 2 +- .../propagate_const.nonmembers/swap.pass.cpp | 2 +- .../file.streams/c.files/cinttypes.pass.cpp | 2 + .../file.streams/c.files/cstdio.pass.cpp | 31 +- .../c.files/gets.compile.fail.cpp | 21 + .../file.streams/c.files/gets.fail.cpp | 21 - .../filebuf.assign/member_swap.pass.cpp | 3 + .../filebuf.assign/move_assign.pass.cpp | 5 +- .../filebuf.assign/nonmember_swap.pass.cpp | 3 + .../fstreams/filebuf.cons/default.pass.cpp | 2 + .../fstreams/filebuf.cons/move.pass.cpp | 9 +- .../filebuf.members/open_path.pass.cpp | 14 +- .../filebuf.members/open_pointer.pass.cpp | 5 +- .../filebuf.virtuals/overflow.pass.cpp | 5 + .../filebuf.virtuals/pbackfail.pass.cpp | 2 + .../filebuf.virtuals/seekoff.pass.cpp | 5 + .../filebuf.virtuals/underflow.pass.cpp | 5 + .../fstream.assign/member_swap.pass.cpp | 3 + .../fstream.assign/move_assign.pass.cpp | 5 +- .../fstream.assign/nonmember_swap.pass.cpp | 3 + .../fstreams/fstream.cons/default.pass.cpp | 2 + .../fstreams/fstream.cons/move.pass.cpp | 29 +- .../fstreams/fstream.cons/path.pass.cpp | 14 +- .../fstreams/fstream.cons/pointer.pass.cpp | 3 + .../fstreams/fstream.cons/string.pass.cpp | 3 + .../fstreams/fstream.members/close.pass.cpp | 3 + .../fstream.members/open_path.pass.cpp | 14 +- .../fstream.members/open_pointer.pass.cpp | 3 + .../fstream.members/open_string.pass.cpp | 3 + .../fstreams/fstream.members/rdbuf.pass.cpp | 3 + .../ifstream.assign/member_swap.pass.cpp | 4 + .../ifstream.assign/move_assign.pass.cpp | 4 +- .../ifstream.assign/nonmember_swap.pass.cpp | 4 + .../fstreams/ifstream.cons/default.pass.cpp | 2 + .../fstreams/ifstream.cons/move.pass.cpp | 8 +- .../fstreams/ifstream.cons/path.pass.cpp | 12 +- .../fstreams/ifstream.cons/pointer.pass.cpp | 5 + .../fstreams/ifstream.cons/string.pass.cpp | 5 + .../fstreams/ifstream.members/close.pass.cpp | 4 + .../ifstream.members/open_path.pass.cpp | 11 +- .../ifstream.members/open_pointer.pass.cpp | 4 + .../ifstream.members/open_string.pass.cpp | 4 + .../fstreams/ifstream.members/rdbuf.pass.cpp | 4 + .../file.streams/fstreams/lit.local.cfg | 2 - .../ofstream.assign/member_swap.pass.cpp | 3 + .../ofstream.assign/move_assign.pass.cpp | 5 +- .../ofstream.assign/nonmember_swap.pass.cpp | 3 + .../fstreams/ofstream.cons/default.pass.cpp | 2 + .../fstreams/ofstream.cons/move.pass.cpp | 9 +- .../fstreams/ofstream.cons/path.pass.cpp | 14 +- .../fstreams/ofstream.cons/pointer.pass.cpp | 3 + .../fstreams/ofstream.cons/string.pass.cpp | 3 + .../fstreams/ofstream.members/close.pass.cpp | 3 + .../ofstream.members/open_path.pass.cpp | 14 +- .../ofstream.members/open_pointer.pass.cpp | 3 + .../ofstream.members/open_string.pass.cpp | 3 + .../fstreams/ofstream.members/rdbuf.pass.cpp | 3 + .../input.output/file.streams/lit.local.cfg | 3 + .../file.streams/nothing_to_do.pass.cpp | 13 - .../Inputs/static_test_env/bad_symlink | 1 - .../Inputs/static_test_env/dir1/dir2/file4 | 0 .../static_test_env/dir1/dir2/symlink_to_dir3 | 1 - .../Inputs/static_test_env/dir1/file1 | 0 .../Inputs/static_test_env/dir1/file2 | 1 - .../Inputs/static_test_env/empty_file | 0 .../Inputs/static_test_env/non_empty_file | 1 - .../Inputs/static_test_env/symlink_to_dir | 1 - .../static_test_env/symlink_to_empty_file | 1 - .../directory_entry.cons/copy.pass.cpp | 2 +- .../directory_entry.cons/copy_assign.pass.cpp | 2 +- .../directory_entry.cons/default.pass.cpp | 2 +- .../default_const.pass.cpp | 3 +- .../directory_entry.cons/move.pass.cpp | 2 +- .../directory_entry.cons/move_assign.pass.cpp | 2 +- .../directory_entry.cons/path.pass.cpp | 44 +- .../directory_entry.io.pass.cpp | 54 + .../directory_entry.mods/assign.pass.cpp | 21 +- .../directory_entry.mods/refresh.pass.cpp | 22 +- .../replace_filename.pass.cpp | 13 +- .../directory_entry.obs/comparisons.pass.cpp | 13 +- .../directory_entry.obs/file_size.pass.cpp | 33 +- .../file_type_obs.pass.cpp | 34 +- .../hard_link_count.pass.cpp | 42 +- .../last_write_time.pass.cpp | 27 +- .../directory_entry.obs/path.pass.cpp | 2 +- .../directory_entry.obs/status.pass.cpp | 7 +- .../symlink_status.pass.cpp | 7 +- .../directory_iterator.members/copy.pass.cpp | 5 +- .../copy_assign.pass.cpp | 11 +- .../directory_iterator.members/ctor.pass.cpp | 29 +- .../default_ctor.pass.cpp | 2 +- .../increment.pass.cpp | 24 +- .../directory_iterator.members/move.pass.cpp | 5 +- .../move_assign.pass.cpp | 16 +- .../begin_end.pass.cpp | 16 +- ...rator_concept_conformance.compile.pass.cpp | 38 + ...range_concept_conformance.compile.pass.cpp | 43 + .../class.directory_iterator/types.pass.cpp | 5 +- .../file_status.cons.pass.cpp | 2 +- .../file_status.mods.pass.cpp | 2 +- .../file_status.obs.pass.cpp | 2 +- .../filesystem_error.members.pass.cpp | 6 +- .../class.path/path.itr/iterator.pass.cpp | 32 +- .../path.member/path.append.pass.cpp | 165 +- .../path.assign/braced_init.pass.cpp | 32 - .../path.member/path.assign/copy.pass.cpp | 9 +- .../path.member/path.assign/move.pass.cpp | 13 +- .../path.member/path.assign/source.pass.cpp | 43 +- .../path.member/path.charconv.pass.cpp | 411 + .../path.member/path.compare.pass.cpp | 24 +- .../path.member/path.concat.pass.cpp | 67 +- .../path.member/path.construct/copy.pass.cpp | 9 +- .../path.construct/default.pass.cpp | 2 +- .../path.member/path.construct/move.pass.cpp | 13 +- .../path.construct/source.pass.cpp | 23 +- .../path.member/path.decompose/empty.fail.cpp | 29 - .../path.decompose/empty.verify.cpp | 27 + .../path.decompose/path.decompose.pass.cpp | 127 +- .../path.gen/lexically_normal.pass.cpp | 30 +- .../lexically_relative_and_proximate.pass.cpp | 44 +- .../generic_string_alloc.pass.cpp | 32 +- .../path.generic.obs/named_overloads.pass.cpp | 35 +- .../path.member/path.modifiers/clear.pass.cpp | 2 +- .../path.modifiers/make_preferred.pass.cpp | 26 +- .../path.modifiers/remove_filename.pass.cpp | 17 +- .../path.modifiers/replace_extension.pass.cpp | 2 +- .../path.modifiers/replace_filename.pass.cpp | 25 +- .../path.member/path.modifiers/swap.pass.cpp | 2 +- .../path.native.obs/c_str.pass.cpp | 5 +- .../path.native.obs/named_overloads.pass.cpp | 14 +- .../path.native.obs/native.pass.cpp | 6 +- .../path.native.obs/operator_string.pass.cpp | 10 +- .../path.native.obs/string_alloc.pass.cpp | 138 - .../tested_in_path_decompose.pass.cpp | 2 +- .../path.nonmember/append_op.fail.cpp | 2 +- .../path.nonmember/append_op.pass.cpp | 2 +- .../path.nonmember/comparison_ops.fail.cpp | 2 +- .../comparison_ops_tested_elsewhere.pass.cpp | 2 +- .../hash_value_tested_elswhere.pass.cpp | 2 +- .../path.nonmember/path.factory.pass.cpp | 29 +- .../path.nonmember/path.io.pass.cpp | 13 +- .../path.io.unicode_bug.pass.cpp | 2 +- .../class.path/path.nonmember/swap.pass.cpp | 36 +- ...range_concept_conformance.compile.pass.cpp | 38 + .../filesystems/class.path/synop.pass.cpp | 15 +- ...range_concept_conformance.compile.pass.cpp | 42 + .../rec.dir.itr.members/copy.pass.cpp | 5 +- .../rec.dir.itr.members/copy_assign.pass.cpp | 26 +- .../rec.dir.itr.members/ctor.pass.cpp | 39 +- .../rec.dir.itr.members/depth.pass.cpp | 9 +- .../disable_recursion_pending.pass.cpp | 5 +- .../rec.dir.itr.members/increment.pass.cpp | 53 +- .../rec.dir.itr.members/move.pass.cpp | 5 +- .../rec.dir.itr.members/move_assign.pass.cpp | 26 +- .../rec.dir.itr.members/pop.pass.cpp | 13 +- .../recursion_pending.pass.cpp | 37 +- .../rec.dir.itr.nonmembers/begin_end.pass.cpp | 16 +- .../fs.enum/enum.copy_options.pass.cpp | 15 +- .../fs.enum/enum.directory_options.pass.cpp | 4 +- .../fs.enum/enum.file_type.pass.cpp | 7 +- .../fs.enum/enum.path.format.pass.cpp | 4 +- .../fs.enum/enum.perm_options.pass.cpp | 4 +- .../filesystems/fs.enum/enum.perms.pass.cpp | 4 +- .../enable_borrowed_range.compile.pass.cpp | 32 + .../enable_view.compile.pass.cpp | 32 + .../file_time_type.pass.cpp | 10 +- ...file_time_type_resolution.compile.pass.cpp | 28 + .../fs.op.absolute/absolute.pass.cpp | 9 +- .../fs.op.canonical/canonical.pass.cpp | 54 +- .../fs.op.funcs/fs.op.copy/copy.pass.cpp | 15 +- .../fs.op.copy_file/copy_file.pass.cpp | 16 +- .../fs.op.copy_file/copy_file_large.pass.cpp | 50 +- .../fs.op.copy_symlink/copy_symlink.pass.cpp | 4 +- .../create_directories.pass.cpp | 75 +- .../create_directory.pass.cpp | 41 +- .../create_directory_with_attributes.pass.cpp | 53 +- .../create_directory_symlink.pass.cpp | 4 +- .../create_hard_link.pass.cpp | 2 +- .../create_symlink.pass.cpp | 26 +- .../fs.op.current_path/current_path.pass.cpp | 18 +- .../fs.op.equivalent/equivalent.pass.cpp | 22 +- .../fs.op.funcs/fs.op.exists/exists.pass.cpp | 35 +- .../fs.op.file_size/file_size.pass.cpp | 23 +- .../fs.op.hard_lk_ct/hard_link_count.pass.cpp | 37 +- .../is_block_file.pass.cpp | 20 +- .../is_character_file.pass.cpp | 20 +- .../fs.op.is_directory/is_directory.pass.cpp | 27 +- .../fs.op.is_empty/is_empty.pass.cpp | 41 +- .../fs.op.is_fifo/is_fifo.pass.cpp | 20 +- .../fs.op.is_other/is_other.pass.cpp | 20 +- .../is_regular_file.pass.cpp | 20 +- .../fs.op.is_socket/is_socket.pass.cpp | 20 +- .../fs.op.is_symlink/is_symlink.pass.cpp | 31 +- .../last_write_time.pass.cpp | 117 +- .../fs.op.permissions/permissions.pass.cpp | 20 +- .../fs.op.proximate/proximate.pass.cpp | 107 +- .../fs.op.read_symlink/read_symlink.pass.cpp | 6 +- .../fs.op.relative/relative.pass.cpp | 78 +- .../fs.op.funcs/fs.op.remove/remove.pass.cpp | 8 +- .../fs.op.remove_all/remove_all.pass.cpp | 12 +- .../fs.op.remove_all/toctou.pass.cpp | 89 + .../fs.op.funcs/fs.op.rename/rename.pass.cpp | 37 +- .../fs.op.resize_file/resize_file.pass.cpp | 2 +- .../fs.op.funcs/fs.op.space/space.pass.cpp | 43 +- .../fs.op.funcs/fs.op.status/status.pass.cpp | 61 +- .../fs.op.status_known/status_known.pass.cpp | 2 +- .../symlink_status.pass.cpp | 54 +- .../temp_directory_path.pass.cpp | 69 +- .../weakly_canonical.pass.cpp | 77 +- .../fs.req.macros/feature_macro.pass.cpp | 30 - .../fs.req.namespace/namespace.fail.cpp | 2 +- .../fs.req.namespace/namespace.pass.cpp | 2 +- .../input.output/filesystems/lit.local.cfg | 14 +- .../input.output.general/lit.local.cfg | 3 + .../ext.manip/get_money.pass.cpp | 4 + .../ext.manip/get_time.pass.cpp | 2 + .../ext.manip/put_money.pass.cpp | 4 + .../ext.manip/put_time.pass.cpp | 2 + .../iostream.assign/member_swap.pass.cpp | 2 + .../iostream.assign/move_assign.pass.cpp | 4 +- .../iostreamclass/iostream.cons/move.pass.cpp | 4 +- .../iostream.cons/streambuf.pass.cpp | 2 + .../bool.pass.cpp | 9 +- .../double.pass.cpp | 9 +- .../float.pass.cpp | 9 +- .../istream.formatted.arithmetic/int.pass.cpp | 9 +- .../long.pass.cpp | 9 +- .../long_double.pass.cpp | 9 +- .../long_long.pass.cpp | 9 +- .../pointer.pass.cpp | 11 +- .../short.pass.cpp | 9 +- .../unsigned_int.pass.cpp | 9 +- .../unsigned_long.pass.cpp | 9 +- .../unsigned_long_long.pass.cpp | 9 +- .../unsigned_short.pass.cpp | 9 +- .../istream_extractors/chart.pass.cpp | 6 + .../istream_extractors/streambuf.pass.cpp | 13 +- .../wchar_t_pointer.pass.cpp | 6 + .../istream.formatted/nothing_to_do.pass.cpp | 13 - .../input.streams/istream.manip/ws.pass.cpp | 8 +- .../istream.rvalue/not_istreamable.verify.cpp | 18 + .../istream.rvalue/rvalue.pass.cpp | 45 +- .../istream.unformatted/get.pass.cpp | 11 +- .../istream.unformatted/get_chart.pass.cpp | 13 +- .../get_pointer_size.pass.cpp | 15 +- .../get_pointer_size_chart.pass.cpp | 15 +- .../get_streambuf.pass.cpp | 13 +- .../get_streambuf_chart.pass.cpp | 15 +- .../getline_pointer_size.pass.cpp | 13 +- .../getline_pointer_size_chart.pass.cpp | 13 +- .../istream.unformatted/ignore.pass.cpp | 11 +- .../istream.unformatted/ignore_0xff.pass.cpp | 2 +- .../istream.unformatted/peek.pass.cpp | 11 +- .../istream.unformatted/putback.pass.cpp | 4 + .../istream.unformatted/read.pass.cpp | 11 +- .../istream.unformatted/readsome.pass.cpp | 2 + .../istream.unformatted/seekg.pass.cpp | 2 + .../istream.unformatted/seekg_off.pass.cpp | 6 +- .../istream.unformatted/sync.pass.cpp | 6 + .../istream.unformatted/tellg.pass.cpp | 2 + .../istream.unformatted/unget.pass.cpp | 4 + .../istream.assign/member_swap.pass.cpp | 2 + .../istream.assign/move_assign.pass.cpp | 4 +- .../istream/istream.cons/copy.fail.cpp | 5 - .../istream/istream.cons/move.pass.cpp | 4 +- .../istream/istream.cons/streambuf.pass.cpp | 2 + .../istream/istream_sentry/ctor.pass.cpp | 59 +- .../iostream.format/lit.local.cfg | 3 + .../iostream.format/nothing_to_do.pass.cpp | 13 - .../ostream.assign/member_swap.pass.cpp | 2 + .../ostream.assign/move_assign.pass.cpp | 4 +- .../output.streams/ostream.cons/move.pass.cpp | 4 +- .../ostream.cons/streambuf.pass.cpp | 2 + .../ostream.formatted/nothing_to_do.pass.cpp | 13 - .../minmax_showbase.pass.cpp | 4 +- .../minus1.pass.cpp | 2 +- .../pointer.volatile.pass.cpp | 94 + .../CharT.pass.cpp | 2 + .../CharT_pointer.pass.cpp | 2 + .../char_to_wide.pass.cpp | 2 + .../char_to_wide_pointer.pass.cpp | 2 + .../ostream.manip/endl.pass.cpp | 2 + .../ostream.manip/ends.pass.cpp | 2 + .../ostream.manip/flush.pass.cpp | 2 + .../ostream.rvalue/CharT_pointer.pass.cpp | 73 - .../ostream.rvalue/not_ostreamable.verify.cpp | 17 + .../ostream.rvalue/rvalue.pass.cpp | 82 + .../ostream.seeks/seekp.pass.cpp | 2 +- .../ostream.seeks/seekp2.pass.cpp | 2 +- .../ostream.unformatted/put.pass.cpp | 24 +- .../ostream.unformatted/write.pass.cpp | 24 +- .../quoted.manip/quoted.pass.cpp | 35 +- .../quoted.manip/quoted_char.fail.cpp | 39 - .../quoted.manip/quoted_char.verify.cpp | 34 + .../quoted.manip/quoted_traits.fail.cpp | 45 - .../quoted.manip/quoted_traits.verify.cpp | 38 + .../std.manip/resetiosflags.pass.cpp | 2 + .../std.manip/setbase.pass.cpp | 2 + .../std.manip/setfill.pass.cpp | 2 + .../std.manip/setiosflags.pass.cpp | 2 + .../std.manip/setprecision.pass.cpp | 2 + .../iostream.format/std.manip/setw.pass.cpp | 4 +- .../iostream.forward/iosfwd.pass.cpp | 43 +- .../iostream.forward/lit.local.cfg | 3 + .../iostream.objects/check-stderr.sh | 4 + .../iostream.objects/check-stdout.sh | 4 + .../iostream.objects/init.pass.cpp | 100 + .../iostream.objects/lit.local.cfg | 3 + .../narrow.stream.objects/cerr.pass.cpp | 32 - .../narrow.stream.objects/cerr.sh.cpp | 28 + .../narrow.stream.objects/cin.pass.cpp | 37 - .../narrow.stream.objects/cin.sh.cpp | 26 + .../narrow.stream.objects/clog.pass.cpp | 26 - .../narrow.stream.objects/clog.sh.cpp | 23 + .../narrow.stream.objects/cout.pass.cpp | 32 - .../narrow.stream.objects/cout.sh.cpp | 23 + .../iostream.objects/send-stdin.sh | 3 + .../wide.stream.objects/wcerr.pass.cpp | 32 - .../wide.stream.objects/wcerr.sh.cpp | 30 + .../wide.stream.objects/wcin.pass.cpp | 37 - .../wide.stream.objects/wcin.sh.cpp | 28 + .../wide.stream.objects/wclog.pass.cpp | 26 - .../wide.stream.objects/wclog.sh.cpp | 25 + .../wide.stream.objects/wcout.pass.cpp | 28 - .../wide.stream.objects/wcout.sh.cpp | 25 + .../fpos/fpos.operations/difference.pass.cpp | 2 +- .../fpos/fpos.operations/fpos.pass.cpp | 101 + .../fpos/fpos.operations/subtraction.pass.cpp | 2 +- .../fpos/nothing_to_do.pass.cpp | 13 - .../ios.base/ios.base.storage/iword.pass.cpp | 2 +- .../ios.base/ios.base.storage/pword.pass.cpp | 2 +- .../ios_Init/ios_Init.multiple.pass.cpp | 12 +- .../ios.base/ios.types/nothing_to_do.pass.cpp | 13 - .../ios.base/nothing_to_do.pass.cpp | 19 - .../ios/basic.ios.members/narrow.pass.cpp | 2 + .../ios/iostate.flags/bool.pass.cpp | 8 +- .../is_error_code_enum_io_errc.pass.cpp | 2 - .../input.output/iostreams.base/lit.local.cfg | 3 + .../std.ios.manip/nothing_to_do.pass.cpp | 13 - .../iostreams.requirements/lit.local.cfg | 3 + .../nothing_to_do.pass.cpp | 13 - test/std/input.output/nothing_to_do.pass.cpp | 13 - .../input.output/stream.buffers/lit.local.cfg | 3 + .../streambuf/streambuf.cons/copy.pass.cpp | 12 +- ...ault.fail.cpp => default.compile.fail.cpp} | 0 .../streambuf/streambuf.cons/default.pass.cpp | 5 + .../streambuf.members/nothing_to_do.pass.cpp | 13 - .../nothing_to_do.pass.cpp | 13 - .../streambuf.assign/assign.pass.cpp | 14 +- .../streambuf.assign/swap.pass.cpp | 14 +- .../streambuf.get.area/gbump.pass.cpp | 2 + .../streambuf.get.area/setg.pass.cpp | 2 + .../streambuf.put.area/pbump.pass.cpp | 2 + .../streambuf.put.area/pbump2gig.pass.cpp | 8 +- .../streambuf.put.area/setp.pass.cpp | 2 + .../streambuf.virtuals/nothing_to_do.pass.cpp | 13 - .../xsputn.PR14074.pass.cpp | 2 +- .../stream.buffers/streambuf/types.pass.cpp | 2 + .../istringstream.assign/member_swap.pass.cpp | 2 + .../istringstream.assign/move.pass.cpp | 4 +- .../nonmember_swap.pass.cpp | 2 + .../istringstream.cons/default.pass.cpp | 24 +- .../istringstream.cons/move.pass.cpp | 4 +- .../istringstream.cons/string.pass.cpp | 2 + .../istringstream.members/str.pass.cpp | 2 + .../input.output/string.streams/lit.local.cfg | 3 + .../ostringstream.assign/member_swap.pass.cpp | 2 + .../ostringstream.assign/move.pass.cpp | 4 +- .../nonmember_swap.pass.cpp | 2 + .../ostringstream.cons/default.pass.cpp | 24 +- .../ostringstream.cons/move.pass.cpp | 4 +- .../ostringstream.cons/string.pass.cpp | 2 + .../ostringstream.members/str.pass.cpp | 2 + .../stringbuf.assign/member_swap.pass.cpp | 2 + .../stringbuf/stringbuf.assign/move.pass.cpp | 2 + .../stringbuf.assign/nonmember_swap.pass.cpp | 2 + .../stringbuf/stringbuf.cons/default.pass.cpp | 27 +- .../stringbuf/stringbuf.cons/move.pass.cpp | 14 +- .../stringbuf/stringbuf.cons/string.pass.cpp | 2 + .../stringbuf/stringbuf.members/str.pass.cpp | 2 + .../stringbuf.virtuals/overflow.pass.cpp | 9 +- .../stringbuf.virtuals/pbackfail.pass.cpp | 9 +- .../stringbuf.virtuals/seekoff.pass.cpp | 2 + .../stringbuf.virtuals/seekpos.pass.cpp | 2 + .../stringbuf.virtuals/setbuf.pass.cpp | 2 + .../stringbuf.virtuals/underflow.pass.cpp | 2 + .../stringstream.cons/default.pass.cpp | 24 +- .../stringstream.cons/move.pass.cpp | 4 +- .../stringstream.cons/move2.pass.cpp | 2 +- .../stringstream.cons/string.pass.cpp | 6 +- .../stringstream.assign/member_swap.pass.cpp | 2 + .../stringstream.assign/move.pass.cpp | 4 +- .../nonmember_swap.pass.cpp | 2 + .../stringstream.members/str.pass.cpp | 2 + .../iterator.container/data.pass.cpp | 2 +- .../iterator.container/empty.array.fail.cpp | 29 - .../iterator.container/empty.array.verify.cpp | 27 + .../empty.container.fail.cpp | 29 - .../empty.container.verify.cpp | 27 + .../empty.initializer_list.fail.cpp | 29 - .../empty.initializer_list.verify.cpp | 27 + .../iterator.container/empty.pass.cpp | 2 +- .../iterator.container/size.pass.cpp | 2 +- .../iterator.container/ssize.pass.cpp | 23 +- .../iterator.basic/deprecated.verify.cpp | 15 + .../iterator.basic/iterator.pass.cpp | 2 + .../iterator.operations/advance.pass.cpp | 99 +- .../iterator.operations/distance.pass.cpp | 50 +- .../iterator.operations/next.pass.cpp | 88 +- .../iterator.operations/prev.pass.cpp | 80 +- .../robust_against_adl.pass.cpp | 36 + .../iterator.traits/const_pointer.pass.cpp | 6 +- .../const_volatile_pointer.pass.cpp | 6 +- .../cxx20_iterator_traits.compile.pass.cpp | 637 + .../iterator.traits/empty.fail.cpp | 64 +- .../iterator.traits/empty.pass.cpp | 2 +- .../iter_reference_t.compile.pass.cpp | 24 + .../iterator.traits/pointer.pass.cpp | 5 +- .../iterator.traits/volatile_pointer.pass.cpp | 6 +- .../nothing_to_do.pass.cpp | 13 - .../constraints.verify.cpp | 26 + .../iterator_count.pass.cpp | 77 + .../iterator_count_sentinel.pass.cpp | 225 + .../iterator_sentinel.pass.cpp | 126 + .../iterator_sentinel.pass.cpp | 237 + .../range.iter.ops.distance/lwg3664.pass.cpp | 73 + .../range.iter.ops.distance/range.pass.cpp | 110 + .../constraints.compile.pass.cpp | 38 + .../range.iter.ops.next/iterator.pass.cpp | 51 + .../iterator_count.pass.cpp | 60 + .../iterator_count_sentinel.pass.cpp | 55 + .../iterator_sentinel.pass.cpp | 86 + .../constraints.compile.pass.cpp | 36 + .../range.iter.ops.prev/iterator.pass.cpp | 45 + .../iterator_count.pass.cpp | 56 + .../iterator_count_sentinel.pass.cpp | 52 + .../range.iter.ops/types.h | 57 + .../contiguous_iterator_tag.pass.cpp | 31 + ...nd.fail.cpp => begin-end.compile.fail.cpp} | 0 .../iterator.range/begin-end.pass.cpp | 6 +- .../iterator.range/begin_array.pass.cpp | 0 .../iterator.range/begin_const.pass.cpp | 0 .../iterator.range/begin_non_const.pass.cpp | 0 .../iterator.range/end_array.pass.cpp | 0 .../iterator.range/end_const.pass.cpp | 0 .../iterator.range/end_non_const.pass.cpp | 0 .../indirectly_movable.compile.pass.cpp | 58 + ...ectly_movable.subsumption.compile.pass.cpp | 30 + ...directly_movable_storable.compile.pass.cpp | 142 + ...able_storable.subsumption.compile.pass.cpp | 31 + .../indirectly_swappable.compile.pass.cpp | 79 + ...tly_swappable.subsumption.compile.pass.cpp | 31 + ...indirect_binary_predicate.compile.pass.cpp | 83 + ...rect_equivalence_relation.compile.pass.cpp | 98 + .../indirect_result_t.compile.pass.cpp | 32 + ...ndirect_strict_weak_order.compile.pass.cpp | 98 + .../indirect_unary_predicate.compile.pass.cpp | 65 + .../indirectly_comparable.compile.pass.cpp | 51 + ...y_regular_unary_invocable.compile.pass.cpp | 88 + ...ndirectly_unary_invocable.compile.pass.cpp | 88 + .../projected/projected.compile.pass.cpp | 65 + .../incrementable_traits.compile.pass.cpp | 239 + .../iter_difference_t.compile.pass.cpp | 59 + ...ndirectly_readable_traits.compile.pass.cpp | 152 + .../readable.traits/iter_value_t.pass.cpp | 74 + .../iterator.concepts/incrementable.h | 183 + .../bidirectional_iterator.compile.pass.cpp | 148 + .../subsumption.compile.pass.cpp | 29 + .../forward_iterator.compile.pass.cpp | 88 + .../subsumption.compile.pass.cpp | 30 + .../incrementable.compile.pass.cpp | 45 + .../subsumption.compile.pass.cpp | 32 + .../input_iterator.compile.pass.cpp | 123 + .../subsumption.compile.pass.cpp | 32 + .../input_or_output_iterator.compile.pass.cpp | 76 + .../subsumption.compile.pass.cpp | 29 + .../output_iterator.compile.pass.cpp | 58 + .../contiguous_iterator.compile.pass.cpp | 211 + .../random_access_iterator.compile.pass.cpp | 183 + .../indirectly_readable.compile.pass.cpp | 198 + .../iter_common_reference_t.compile.pass.cpp | 59 + .../sentinel_for.compile.pass.cpp | 56 + .../sentinel_for.subsumption.compile.pass.cpp | 32 + .../sized_sentinel_for.compile.pass.cpp | 84 + .../weakly_incrementable.compile.pass.cpp | 70 + .../indirectly_writable.compile.pass.cpp | 54 + .../iter_move.nodiscard.verify.cpp | 37 + .../iterator.cust.move/iter_move.pass.cpp | 193 + .../iter_rvalue_reference_t.pass.cpp | 25 + .../iterator.cust.swap/iter_swap.pass.cpp | 226 + .../unqualified_lookup_wrapper.h | 79 + .../nothing_to_do.pass.cpp | 13 - .../iterators.general/nothing_to_do.pass.cpp | 13 - .../counted.iterator/arrow.pass.cpp | 55 + .../counted.iterator/assign.pass.cpp | 128 + .../counted.iterator/base.pass.cpp | 114 + .../counted.iterator/compare.pass.cpp | 112 + .../counted.iterator/count.pass.cpp | 82 + .../counted.iterator/ctor.conv.pass.cpp | 77 + .../counted.iterator/ctor.default.pass.cpp | 35 + .../counted.iterator/ctor.iter.pass.cpp | 92 + .../counted.iterator/decrement.pass.cpp | 76 + .../counted.iterator/deref.pass.cpp | 108 + .../counted.iterator/increment.cpp | 139 + .../counted.iterator/iter_move.pass.cpp | 83 + .../counted.iterator/iter_swap.pass.cpp | 106 + ...rator_concept_conformance.compile.pass.cpp | 30 + .../iterator_traits.compile.pass.cpp | 69 + .../member_types.compile.pass.cpp | 62 + .../minus.default_sentinel.pass.cpp | 88 + .../counted.iterator/minus.eq.pass.cpp | 60 + .../counted.iterator/minus.iter.pass.cpp | 122 + .../counted.iterator/minus.size.pass.cpp | 78 + .../counted.iterator/plus.pass.cpp | 110 + .../counted.iterator/subscript.pass.cpp | 61 + .../three_way_compare.pass.cpp | 86 + .../default.sentinel.pass.cpp | 33 + .../container.compile.fail.cpp | 26 + .../back.insert.iter.cons/container.fail.cpp | 25 - .../back.insert.iter.cons/container.pass.cpp | 15 +- .../back.insert.iter.op++/post.pass.cpp | 13 +- .../back.insert.iter.op++/pre.pass.cpp | 15 +- .../back.insert.iter.op=/lv_value.pass.cpp | 11 +- .../back.insert.iter.op=/rv_value.pass.cpp | 13 +- .../back.insert.iter.op_astrk/test.pass.cpp | 15 +- .../back.inserter/test.pass.cpp | 30 +- .../nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 28 + .../back.insert.iterator/types.pass.cpp | 16 +- .../container.compile.fail.cpp | 26 + .../front.insert.iter.cons/container.fail.cpp | 25 - .../front.insert.iter.cons/container.pass.cpp | 15 +- .../front.insert.iter.op++/post.pass.cpp | 15 +- .../front.insert.iter.op++/pre.pass.cpp | 15 +- .../front.insert.iter.op=/lv_value.pass.cpp | 15 +- .../front.insert.iter.op=/rv_value.pass.cpp | 15 +- .../front.insert.iter.op_astrk/test.pass.cpp | 15 +- .../front.inserter/test.pass.cpp | 26 +- .../nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 28 + .../front.insert.iterator/types.pass.cpp | 16 +- .../insert.iter.cons/test.pass.cpp | 15 +- .../insert.iter.op++/post.pass.cpp | 15 +- .../insert.iter.op++/pre.pass.cpp | 15 +- .../insert.iter.op=/rv_value.pass.cpp | 2 +- .../insert.iter.op_astrk/test.pass.cpp | 15 +- .../insert.iter.ops/inserter/test.pass.cpp | 15 +- .../insert.iter.ops/nothing_to_do.pass.cpp | 13 - .../cxx20_iter_member.pass.cpp | 64 + ...rator_concept_conformance.compile.pass.cpp | 27 + .../insert.iterator/types.pass.cpp | 16 +- .../insert.iterators/nothing_to_do.pass.cpp | 13 - .../iterators.common/arrow.pass.cpp | 89 + .../iterators.common/assign.pass.cpp | 143 + .../constraints.compile.pass.cpp | 28 + .../iterators.common/ctor.converting.pass.cpp | 48 + .../iterators.common/ctor.default.pass.cpp | 41 + .../iterators.common/ctor.iter.pass.cpp | 50 + .../iterators.common/ctor.sentinel.pass.cpp | 63 + .../iterators.common/deref.pass.cpp | 146 + .../iterators.common/eq.pass.cpp | 167 + .../iterators.common/iter_move.pass.cpp | 93 + .../iterators.common/iter_swap.pass.cpp | 123 + .../iterator_traits.compile.pass.cpp | 136 + .../iterators.common/minus.pass.cpp | 66 + .../iterators.common/plus_plus.pass.cpp | 183 + .../predef.iterators/iterators.common/types.h | 266 + .../make_move_iterator.pass.cpp | 4 +- .../move.iter.op.comp/op_eq.pass.cpp | 4 +- .../move.iter.op.comp/op_neq.pass.cpp | 4 +- .../move.iter.op.const/convert.fail.cpp | 39 - .../move.iter.op.const/convert.pass.cpp | 4 +- .../ctor.convert.LWG3435.verify.cpp | 25 + .../ctor.iter.explicit.verify.cpp | 23 + .../move.iter.op.const/default.pass.cpp | 2 +- .../move.iter.op.const/iter.fail.cpp | 32 - .../move.iter.op.const/iter.pass.cpp | 2 +- .../move.iter.op.incr/post.pass.cpp | 16 +- .../move.iter.op.incr/pre.pass.cpp | 2 +- .../move.iter.op=/assign.LWG3435.verify.cpp | 26 + .../move.iter.op=/move_iterator.fail.cpp | 40 - .../move.iter.op=/move_iterator.pass.cpp | 45 +- .../move.iter.ops/nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 26 + .../move.iterator/types.pass.cpp | 21 +- .../move.iterators/nothing_to_do.pass.cpp | 13 - .../predef.iterators/nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 52 + .../reverse.iterators/nothing_to_do.pass.cpp | 13 - .../reverse.iter.cmp/equal.pass.cpp | 47 + .../reverse.iter.cmp/greater-equal.pass.cpp | 47 + .../reverse.iter.cmp/greater.pass.cpp | 47 + .../reverse.iter.cmp/less-equal.pass.cpp | 47 + .../reverse.iter.cmp/less.pass.cpp | 47 + .../reverse.iter.cmp/not-equal.pass.cpp | 47 + .../reverse.iter.cmp/three-way.pass.cpp | 104 + .../assign.LWG3435.verify.cpp | 26 + .../reverse.iter.cons/assign.pass.cpp | 80 + .../reverse.iter.cons/ctor.default.pass.cpp | 40 + .../ctor.iter.explicit.verify.cpp | 23 + .../reverse.iter.cons/ctor.iter.pass.cpp | 41 + .../ctor.reverse_iterator.LWG3435.verify.cpp | 25 + .../ctor.reverse_iterator.pass.cpp | 46 + .../reverse.iter.conv/base.pass.cpp | 37 + .../reverse.iter.elem/arrow.pass.cpp | 118 + .../reverse.iter.elem/bracket.pass.cpp | 47 + .../reverse.iter.elem/dereference.pass.cpp | 61 + .../decrement-assign.pass.cpp | 43 + .../increment-assign.pass.cpp | 43 + .../reverse.iter.nav/minus.pass.cpp | 42 + .../reverse.iter.nav/plus.pass.cpp | 42 + .../reverse.iter.nav/postdecrement.pass.cpp | 43 + .../reverse.iter.nav/postincrement.pass.cpp | 43 + .../reverse.iter.nav/predecrement.pass.cpp | 43 + .../reverse.iter.nav/preincrement.pass.cpp | 43 + .../make_reverse_iterator.pass.cpp | 45 + .../reverse.iter.nonmember/minus.pass.cpp | 67 + .../reverse.iter.nonmember/plus.pass.cpp | 42 + .../reverse.iter.ops/nothing_to_do.pass.cpp | 13 - .../reverse.iter.cons/default.pass.cpp | 45 - .../reverse.iter.cons/iter.fail.cpp | 32 - .../reverse.iter.cons/iter.pass.cpp | 47 - .../reverse_iterator.fail.cpp | 39 - .../reverse_iterator.pass.cpp | 55 - .../tested_elsewhere.pass.cpp | 13 - .../make_reverse_iterator.pass.cpp | 52 - .../reverse.iter.op!=/test.pass.cpp | 58 - .../reverse.iter.op++/post.pass.cpp | 54 - .../reverse.iter.op++/pre.pass.cpp | 55 - .../reverse.iter.op+/difference_type.pass.cpp | 53 - .../difference_type.pass.cpp | 50 - .../reverse.iter.op--/post.pass.cpp | 54 - .../reverse.iter.op--/pre.pass.cpp | 55 - .../reverse.iter.op-/difference_type.pass.cpp | 53 - .../difference_type.pass.cpp | 50 - .../reverse.iter.op.star/op_star.pass.cpp | 63 - .../reverse_iterator.fail.cpp | 40 - .../reverse_iterator.pass.cpp | 60 - .../reverse.iter.op==/test.pass.cpp | 59 - .../reverse.iter.opdiff/test.pass.cpp | 58 - .../reverse.iter.opgt/test.pass.cpp | 58 - .../reverse.iter.opgt=/test.pass.cpp | 58 - .../difference_type.pass.cpp | 50 - .../reverse.iter.oplt/test.pass.cpp | 58 - .../reverse.iter.oplt=/test.pass.cpp | 58 - .../reverse.iter.opref/op_arrow.pass.cpp | 120 - .../difference_type.pass.cpp | 54 - .../nothing_to_do.pass.cpp | 13 - .../reverse.iterator/types.pass.cpp | 63 - .../reverse.iterators/types.pass.cpp | 83 + .../unreachable_sentinel.pass.cpp | 69 + ...ault.fail.cpp => default.compile.fail.cpp} | 0 .../istream.iterator.cons/default.pass.cpp | 4 - ...rator_concept_conformance.compile.pass.cpp | 28 + .../istream.iterator/types.pass.cpp | 37 +- .../istreambuf.iterator.cons/default.pass.cpp | 3 + .../istreambuf.iterator.cons/istream.pass.cpp | 2 + .../istreambuf.iterator.cons/proxy.pass.cpp | 2 + .../streambuf.pass.cpp | 2 + .../istreambuf.iterator_equal/equal.pass.cpp | 2 + .../not_equal.pass.cpp | 2 + .../dereference.pass.cpp | 2 + .../istreambuf.iterator_op==/equal.pass.cpp | 2 + .../post_increment.pass.cpp | 2 + .../pre_increment.pass.cpp | 2 + .../istreambuf.iterator_proxy/proxy.pass.cpp | 8 +- ...rator_concept_conformance.compile.pass.cpp | 29 + .../istreambuf.iterator/types.pass.cpp | 34 +- .../iterators/stream.iterators/lit.local.cfg | 3 + .../stream.iterators/nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 28 + .../ostream_delim.pass.cpp | 2 + .../ostream.iterator.ops/assign_t.pass.cpp | 4 +- .../ostream.iterator/types.pass.cpp | 45 +- ...rator_concept_conformance.compile.pass.cpp | 29 + .../ostreambuf.iter.cons/ostream.pass.cpp | 2 + .../ostreambuf.iter.cons/streambuf.pass.cpp | 2 + .../ostreambuf.iter.ops/assign_c.pass.cpp | 2 + .../ostreambuf.iter.ops/deref.pass.cpp | 2 + .../ostreambuf.iter.ops/failed.pass.cpp | 2 + .../ostreambuf.iter.ops/increment.pass.cpp | 2 + .../ostreambuf.iterator/types.pass.cpp | 48 +- .../compare_partial_order_fallback.pass.cpp | 326 + .../compare_strong_order_fallback.pass.cpp | 530 + .../compare_weak_order_fallback.pass.cpp | 579 + .../cmp/cmp.alg/partial_order.pass.cpp | 255 + .../cmp/cmp.alg/strong_order.pass.cpp | 467 + .../strong_order_long_double.verify.cpp | 32 + .../cmp/cmp.alg/weak_order.pass.cpp | 514 + .../cmp.categories.pre/zero_type.verify.cpp | 59 + .../common_comparison_category.pass.cpp | 41 +- .../three_way_comparable.compile.pass.cpp | 227 + ...three_way_comparable_with.compile.pass.cpp | 227 + .../cmp/cmp.partialord/partialord.pass.cpp | 70 +- .../compare_three_way_result.compile.pass.cpp | 89 + .../cmp/cmp.strongeq/cmp.strongeq.pass.cpp | 97 - .../cmp/cmp.strongord/strongord.pass.cpp | 69 +- .../cmp/cmp.weakeq/cmp.weakeq.pass.cpp | 71 - .../cmp/cmp.weakord/weakord.pass.cpp | 50 +- .../cmp/compare.syn/named_functions.pass.cpp | 109 + .../cstdint/cstdint.syn/cstdint.pass.cpp | 9 +- .../language.support/nothing_to_do.pass.cpp | 13 - .../operator_bool.pass.cpp | 56 + .../equal_comp.pass.cpp | 59 + .../less_comp.pass.cpp | 66 + .../coroutine.handle.completion/done.pass.cpp | 43 + .../coroutine.handle.con/assign.pass.cpp | 54 + .../coroutine.handle.con/construct.pass.cpp | 49 + .../coroutine.handle.export/address.pass.cpp | 53 + .../from_address.pass.cpp | 58 + .../coroutine.handle.hash/hash.pass.cpp | 63 + .../noop_coroutine.pass.cpp | 79 + .../coroutine.handle.prom/promise.pass.cpp | 83 + .../destroy.pass.cpp | 60 + .../resume.pass.cpp | 78 + .../coroutine.handle/void_handle.pass.cpp | 51 + .../coroutine.traits/promise_type.pass.cpp | 77 + .../suspend_always.pass.cpp | 76 + .../suspend_never.pass.cpp | 85 + .../end.to.end/await_result.pass.cpp | 70 + .../end.to.end/bool_await_suspend.pass.cpp | 70 + .../end.to.end/expected.pass.cpp | 88 + .../end.to.end/fullexpr-dtor.pass.cpp | 110 + .../end.to.end/generator.pass.cpp | 161 + .../support.coroutines/end.to.end/go.pass.cpp | 174 + .../end.to.end/multishot_func.pass.cpp | 88 + .../end.to.end/oneshot_func.pass.cpp | 73 + .../support.dynamic/align_val_t.pass.cpp | 6 +- .../alloc.errors/nothing_to_do.pass.cpp | 13 - .../set.new.handler/get_new_handler.pass.cpp | 7 + .../destroying_delete_t.pass.cpp | 8 +- .../destroying_delete_t_declaration.pass.cpp | 6 +- .../delete_align_val_t_replace.pass.cpp | 52 +- .../new.delete.array/new_align_val_t.pass.cpp | 32 +- .../new_align_val_t_nothrow.pass.cpp | 32 +- .../new_align_val_t_nothrow_replace.pass.cpp | 45 +- .../new_align_val_t_replace.pass.cpp | 7 +- .../new_array_nothrow.pass.cpp | 1 + .../new_array_nothrow_replace.pass.cpp | 6 +- .../new_array_replace.pass.cpp | 7 +- .../new.delete.array/new_size.sh.cpp | 27 - .../new.delete.array/new_size.verify.cpp | 23 + .../new.delete.array/new_size_align.sh.cpp | 27 - .../new_size_align.verify.cpp | 27 + .../new_size_align_nothrow.sh.cpp | 27 - .../new_size_align_nothrow.verify.cpp | 27 + .../new.delete.array/new_size_nothrow.sh.cpp | 27 - .../new_size_nothrow.verify.cpp | 23 + .../sized_delete_array11.pass.cpp | 2 +- .../sized_delete_array14.pass.cpp | 5 +- ...d_delete_array_fsizeddeallocation.pass.cpp | 81 + ...zed_delete_array_fsizeddeallocation.sh.cpp | 89 - .../new_array_ptr.fail.cpp | 27 - .../new_array_ptr.verify.cpp | 25 + .../new.delete.placement/new_ptr.fail.cpp | 27 - .../new.delete.placement/new_ptr.verify.cpp | 25 + .../delete_align_val_t_replace.pass.cpp | 48 +- .../new_align_val_t.pass.cpp | 32 +- .../new_align_val_t_nothrow.pass.cpp | 32 +- .../new_align_val_t_nothrow_replace.pass.cpp | 46 +- .../new_align_val_t_replace.pass.cpp | 7 +- .../new_nothrow_replace.pass.cpp | 6 +- .../new.delete.single/new_replace.pass.cpp | 1 + .../new.delete.single/new_size.fail.cpp | 26 - .../new.delete.single/new_size.verify.cpp | 24 + .../new.delete.single/new_size_align.sh.cpp | 27 - .../new_size_align.verify.cpp | 27 + .../new_size_align_nothrow.sh.cpp | 27 - .../new_size_align_nothrow.verify.cpp | 27 + .../new_size_nothrow.fail.cpp | 26 - .../new_size_nothrow.verify.cpp | 24 + .../new.delete.single/sized_delete11.pass.cpp | 2 +- .../new.delete.single/sized_delete14.pass.cpp | 5 +- .../sized_delete_fsizeddeallocation.pass.cpp | 72 + .../sized_delete_fsizeddeallocation.sh.cpp | 79 - .../new.delete/nothing_to_do.pass.cpp | 13 - .../support.dynamic/nothrow_t.fail.cpp | 6 +- .../ptr.launder/launder.nodiscard.fail.cpp | 28 - .../ptr.launder/launder.nodiscard.verify.cpp | 26 + .../ptr.launder/launder.pass.cpp | 2 +- .../ptr.launder/launder.types.fail.cpp | 3 +- .../except.nested/rethrow_if_nested.pass.cpp | 6 +- .../except.nested/rethrow_nested.pass.cpp | 2 +- .../except.nested/throw_with_nested.pass.cpp | 2 +- .../nothing_to_do.pass.cpp | 13 - .../propagation/current_exception.pass.cpp | 6 +- .../propagation/exception_ptr.pass.cpp | 3 +- .../propagation/make_exception_ptr.pass.cpp | 2 +- .../propagation/rethrow_exception.pass.cpp | 2 +- .../uncaught/uncaught_exception.pass.cpp | 2 +- .../uncaught/uncaught_exceptions.pass.cpp | 16 +- .../support.initlist.access/access.pass.cpp | 8 +- .../support.initlist.cons/default.pass.cpp | 4 +- .../support.initlist.range/begin_end.pass.cpp | 8 +- .../support.initlist/types.pass.cpp | 2 +- .../support.limits/c.limits/cfloat.pass.cpp | 8 +- .../limits/is_specialized.pass.cpp | 7 +- .../const_data_members.pass.cpp | 4 +- .../denorm_min.pass.cpp | 4 +- .../numeric.limits.members/digits.pass.cpp | 4 +- .../numeric.limits.members/digits10.pass.cpp | 4 +- .../numeric.limits.members/epsilon.pass.cpp | 4 +- .../has_denorm.pass.cpp | 4 +- .../has_denorm_loss.pass.cpp | 4 +- .../has_infinity.pass.cpp | 4 +- .../has_quiet_NaN.pass.cpp | 4 +- .../has_signaling_NaN.pass.cpp | 4 +- .../numeric.limits.members/infinity.pass.cpp | 4 +- .../is_bounded.pass.cpp | 4 +- .../numeric.limits.members/is_exact.pass.cpp | 4 +- .../numeric.limits.members/is_iec559.pass.cpp | 4 +- .../is_integer.pass.cpp | 4 +- .../numeric.limits.members/is_modulo.pass.cpp | 4 +- .../numeric.limits.members/is_signed.pass.cpp | 4 +- .../numeric.limits.members/lowest.pass.cpp | 11 +- .../numeric.limits.members/max.pass.cpp | 11 +- .../max_digits10.pass.cpp | 4 +- .../max_exponent.pass.cpp | 4 +- .../max_exponent10.pass.cpp | 4 +- .../numeric.limits.members/min.pass.cpp | 11 +- .../min_exponent.pass.cpp | 4 +- .../min_exponent10.pass.cpp | 4 +- .../numeric.limits.members/quiet_NaN.pass.cpp | 4 +- .../numeric.limits.members/radix.pass.cpp | 4 +- .../round_error.pass.cpp | 4 +- .../round_style.pass.cpp | 4 +- .../signaling_NaN.pass.cpp | 4 +- .../tinyness_before.pass.cpp | 4 +- .../numeric.limits.members/traps.pass.cpp | 4 +- .../support.limits/nothing_to_do.pass.cpp | 13 - .../algorithm.version.pass.cpp | 177 +- .../any.version.pass.cpp | 19 +- .../array.version.pass.cpp | 86 +- .../atomic.version.pass.cpp | 295 +- .../barrier.version.pass.cpp | 77 + .../bit.version.pass.cpp | 146 +- .../support.limits.general/charconv.pass.cpp | 33 - .../charconv.version.pass.cpp | 84 + .../chrono.version.pass.cpp | 30 +- .../cmath.version.pass.cpp | 63 +- .../compare.version.pass.cpp | 35 +- .../complex.version.pass.cpp | 62 +- .../concepts.version.pass.cpp | 66 +- .../coroutine.version.pass.cpp | 63 + .../cstddef.version.pass.cpp | 19 +- .../deque.version.pass.cpp | 51 +- .../exception.version.pass.cpp | 19 +- .../execution.version.pass.cpp | 88 +- .../filesystem.version.pass.cpp | 80 +- .../format.version.pass.cpp | 77 + .../forward_list.version.pass.cpp | 93 +- .../functional.version.pass.cpp | 249 +- .../iomanip.version.pass.cpp | 21 +- .../istream.version.pass.cpp | 35 +- .../iterator.version.pass.cpp | 144 +- .../latch.version.pass.cpp | 77 + .../limits.version.pass.cpp | 33 +- .../list.version.pass.cpp | 93 +- .../locale.version.pass.cpp | 35 +- .../map.version.pass.cpp | 126 +- .../memory.version.pass.cpp | 446 +- .../memory_resource.version.pass.cpp | 35 - .../mutex.version.pass.cpp | 21 +- .../new.version.pass.cpp | 89 +- .../numbers.version.pass.cpp | 75 + .../numeric.version.pass.cpp | 82 +- .../optional.version.pass.cpp | 47 +- .../ostream.version.pass.cpp | 35 +- .../queue.version.pass.cpp | 60 + .../ranges.version.pass.cpp | 107 + .../regex.version.pass.cpp | 21 +- .../scoped_allocator.version.pass.cpp | 19 +- .../semaphore.version.pass.cpp | 77 + .../set.version.pass.cpp | 113 +- .../shared_mutex.version.pass.cpp | 62 +- .../span.version.pass.cpp | 63 + .../stack.version.pass.cpp | 60 + .../string.version.pass.cpp | 205 +- .../string_view.version.pass.cpp | 139 +- .../thread.version.pass.cpp | 77 + .../tuple.version.pass.cpp | 119 +- .../type_traits.version.pass.cpp | 448 +- .../typeinfo.version.pass.cpp | 66 + .../unordered_map.version.pass.cpp | 144 +- .../unordered_set.version.pass.cpp | 131 +- .../utility.version.pass.cpp | 211 +- .../variant.version.pass.cpp | 27 +- .../vector.version.pass.cpp | 101 +- .../version.version.pass.cpp | 3401 ++++- .../support.limits/version.pass.cpp | 2 +- .../support.rtti/type.info/type_info.pass.cpp | 2 + .../type.info/type_info_hash.pass.cpp | 2 + .../cstdlib.aligned_alloc.compile.pass.cpp | 24 + .../support.runtime/cstdlib.pass.cpp | 16 +- .../support.runtime/ctime.pass.cpp | 16 +- .../ctime.timespec.compile.pass.cpp | 34 + .../support.start.term/quick_exit.pass.cpp | 19 +- .../quick_exit_check1.fail.cpp | 27 - .../quick_exit_check2.fail.cpp | 26 - .../support.types/byte.pass.cpp | 2 +- .../support.types/byteops/and.assign.pass.cpp | 2 +- .../support.types/byteops/and.pass.cpp | 2 +- .../byteops/enum_direct_init.pass.cpp | 5 +- .../byteops/lshift.assign.compile.fail.cpp | 29 + .../byteops/lshift.assign.fail.cpp | 32 - .../byteops/lshift.assign.pass.cpp | 2 +- .../byteops/lshift.compile.fail.cpp | 24 + .../support.types/byteops/lshift.fail.cpp | 24 - .../support.types/byteops/lshift.pass.cpp | 2 +- .../support.types/byteops/not.pass.cpp | 2 +- .../support.types/byteops/or.assign.pass.cpp | 2 +- .../support.types/byteops/or.pass.cpp | 2 +- .../byteops/rshift.assign.compile.fail.cpp | 29 + .../byteops/rshift.assign.fail.cpp | 32 - .../byteops/rshift.assign.pass.cpp | 2 +- .../byteops/rshift.compile.fail.cpp | 24 + .../support.types/byteops/rshift.fail.cpp | 24 - .../support.types/byteops/rshift.pass.cpp | 2 +- .../byteops/to_integer.compile.fail.cpp | 24 + .../support.types/byteops/to_integer.fail.cpp | 24 - .../support.types/byteops/to_integer.pass.cpp | 3 +- .../support.types/byteops/xor.assign.pass.cpp | 2 +- .../support.types/byteops/xor.pass.cpp | 2 +- .../max_align_t.compile.pass.cpp | 30 + .../support.types/max_align_t.pass.cpp | 45 - .../support.types/nullptr_t.pass.cpp | 8 - ... nullptr_t_integral_cast.compile.fail.cpp} | 0 .../nullptr_t_integral_cast.pass.cpp | 6 +- .../support.types/offsetof.pass.cpp | 2 +- .../cpo.compile.pass.cpp | 98 + .../niebloid.compile.pass.cpp | 189 + .../expos.only.func/synth_three_way.pass.cpp | 184 + .../localization/c.locales/clocale.pass.cpp | 6 - test/std/localization/lit.local.cfg | 3 + .../locale.collate.byname/compare.pass.cpp | 11 +- .../locale.collate.byname/hash.pass.cpp | 5 + .../locale.collate.byname/transform.pass.cpp | 4 + .../locale.collate.byname/types.pass.cpp | 2 + .../locale.collate/ctor.pass.cpp | 3 + .../locale.collate.members/compare.pass.cpp | 5 + .../locale.collate.members/hash.pass.cpp | 5 + .../locale.collate.members/transform.pass.cpp | 2 + .../locale.collate/types.pass.cpp | 2 + .../category.collate/nothing_to_do.pass.cpp | 13 - .../category.ctype/ctype_base.pass.cpp | 5 - .../facet.ctype.char.dtor/dtor.pass.cpp | 3 +- .../classic_table.pass.cpp | 2 + .../table_size.pass.cpp | 31 + ...ame_char16_t_char.depr_in_cxx20.verify.cpp | 29 + ...ame_char32_t_char.depr_in_cxx20.verify.cpp | 29 + .../ctor_char16_t.pass.cpp | 3 + .../ctor_char16_t_char8_t.pass.cpp | 80 + .../ctor_char32_t.pass.cpp | 3 + .../ctor_char32_t_char8_t.pass.cpp | 80 + .../ctor_wchar_t.pass.cpp | 2 + ...cvt_char16_t_char.depr_in_cxx20.verify.cpp | 29 + ...cvt_char32_t_char.depr_in_cxx20.verify.cpp | 29 + .../locale.codecvt/ctor_char16_t.pass.cpp | 3 + .../ctor_char16_t_char8_t.pass.cpp | 55 + .../locale.codecvt/ctor_char32_t.pass.cpp | 3 + .../ctor_char32_t_char8_t.pass.cpp | 55 + .../locale.codecvt/ctor_wchar_t.pass.cpp | 2 + .../char16_t_always_noconv.pass.cpp | 3 + .../char16_t_char8_t_always_noconv.pass.cpp | 31 + .../char16_t_char8_t_encoding.pass.cpp | 31 + .../char16_t_char8_t_in.pass.cpp | 41 + .../char16_t_char8_t_length.pass.cpp | 36 + .../char16_t_char8_t_max_length.pass.cpp | 31 + .../char16_t_char8_t_out.pass.cpp | 42 + .../char16_t_char8_t_unshift.pass.cpp | 35 + .../char16_t_encoding.pass.cpp | 3 + .../char16_t_in.pass.cpp | 8 + .../char16_t_length.pass.cpp | 8 + .../char16_t_max_length.pass.cpp | 3 + .../char16_t_out.pass.cpp | 8 + .../char16_t_unshift.pass.cpp | 3 + .../char32_t_always_noconv.pass.cpp | 3 + .../char32_t_char8_t_always_noconv.pass.cpp | 31 + .../char32_t_char8_t_encoding.pass.cpp | 31 + .../char32_t_char8_t_in.pass.cpp | 41 + .../char32_t_char8_t_length.pass.cpp | 36 + .../char32_t_char8_t_max_length.pass.cpp | 31 + .../char32_t_char8_t_out.pass.cpp | 42 + .../char32_t_char8_t_unshift.pass.cpp | 35 + .../char32_t_encoding.pass.cpp | 3 + .../char32_t_in.pass.cpp | 8 + .../char32_t_length.pass.cpp | 8 + .../char32_t_max_length.pass.cpp | 3 + .../char32_t_out.pass.cpp | 8 + .../char32_t_unshift.pass.cpp | 3 + .../utf_sanity_check.pass.cpp | 296 +- .../wchar_t_always_noconv.pass.cpp | 2 + .../wchar_t_encoding.pass.cpp | 2 + .../wchar_t_in.pass.cpp | 2 + .../wchar_t_length.pass.cpp | 2 + .../wchar_t_max_length.pass.cpp | 2 + .../wchar_t_out.pass.cpp | 2 + .../wchar_t_unshift.pass.cpp | 2 + .../locale.codecvt/types_char16_t.pass.cpp | 3 + .../types_char16_t_char8_t.pass.cpp | 47 + .../locale.codecvt/types_char32_t.pass.cpp | 3 + .../types_char32_t_char8_t.pass.cpp | 47 + .../locale.codecvt/types_wchar_t.pass.cpp | 2 + .../locale.ctype.byname/is_1.pass.cpp | 2 + .../locale.ctype.byname/is_many.pass.cpp | 2 + .../locale.ctype.byname/mask.pass.cpp | 59 +- .../locale.ctype.byname/narrow_1.pass.cpp | 2 + .../locale.ctype.byname/narrow_many.pass.cpp | 2 + .../locale.ctype.byname/scan_is.pass.cpp | 2 + .../locale.ctype.byname/scan_not.pass.cpp | 2 + .../locale.ctype.byname/tolower_1.pass.cpp | 2 + .../locale.ctype.byname/tolower_many.pass.cpp | 2 + .../locale.ctype.byname/toupper_1.pass.cpp | 2 + .../locale.ctype.byname/toupper_many.pass.cpp | 2 + .../locale.ctype.byname/types.pass.cpp | 4 + .../locale.ctype.byname/widen_1.pass.cpp | 3 + .../locale.ctype.byname/widen_many.pass.cpp | 3 + .../category.ctype/locale.ctype/ctor.pass.cpp | 2 + .../locale.ctype.members/is_1.pass.cpp | 2 + .../locale.ctype.members/is_many.pass.cpp | 2 + .../locale.ctype.members/narrow_1.pass.cpp | 2 + .../locale.ctype.members/narrow_many.pass.cpp | 2 + .../locale.ctype.members/scan_is.pass.cpp | 2 + .../locale.ctype.members/scan_not.pass.cpp | 2 + .../locale.ctype.members/tolower_1.pass.cpp | 2 + .../tolower_many.pass.cpp | 2 + .../locale.ctype.members/toupper_1.pass.cpp | 2 + .../toupper_many.pass.cpp | 2 + .../locale.ctype.members/widen_1.pass.cpp | 2 + .../locale.ctype.members/widen_many.pass.cpp | 2 + .../locale.ctype/types.pass.cpp | 2 + .../category.ctype/with_public_dtor.hpp | 19 + .../locale.messages/types.pass.cpp | 7 +- .../category.messages/nothing_to_do.pass.cpp | 13 - .../get_long_double_en_US.pass.cpp | 134 +- .../get_long_double_fr_FR.pass.cpp | 141 +- .../get_long_double_ru_RU.pass.cpp | 159 +- .../get_long_double_zh_CN.pass.cpp | 127 +- .../get_string_en_US.pass.cpp | 134 +- .../locale.money.get/types.pass.cpp | 9 +- .../put_long_double_en_US.pass.cpp | 8 +- .../put_long_double_fr_FR.pass.cpp | 25 +- .../put_long_double_ru_RU.pass.cpp | 39 +- .../put_long_double_zh_CN.pass.cpp | 11 +- .../put_string_en_US.pass.cpp | 9 +- .../locale.money.put/types.pass.cpp | 9 +- .../curr_symbol.pass.cpp | 31 +- .../decimal_point.pass.cpp | 30 +- .../frac_digits.pass.cpp | 12 + .../grouping.pass.cpp | 17 +- .../neg_format.pass.cpp | 17 +- .../negative_sign.pass.cpp | 14 + .../pos_format.pass.cpp | 17 +- .../positive_sign.pass.cpp | 12 + .../thousands_sep.pass.cpp | 54 +- .../curr_symbol.pass.cpp | 4 + .../decimal_point.pass.cpp | 4 + .../frac_digits.pass.cpp | 4 + .../grouping.pass.cpp | 4 + .../neg_format.pass.cpp | 4 + .../negative_sign.pass.cpp | 4 + .../pos_format.pass.cpp | 4 + .../positive_sign.pass.cpp | 4 + .../thousands_sep.pass.cpp | 4 + .../locale.moneypunct/money_base.pass.cpp | 2 +- .../locale.moneypunct/types.pass.cpp | 17 +- .../category.monetary/nothing_to_do.pass.cpp | 13 - .../facet.num.put.members/put_double.pass.cpp | 7 +- .../put_long_double.pass.cpp | 13 +- .../locale.nm.put/types.pass.cpp | 7 +- .../facet.num.get.members/get_bool.pass.cpp | 86 +- .../facet.num.get.members/get_double.pass.cpp | 117 +- .../facet.num.get.members/get_float.pass.cpp | 89 +- .../facet.num.get.members/get_long.pass.cpp | 239 +- .../get_long_double.pass.cpp | 119 +- .../get_long_long.pass.cpp | 32 +- .../get_pointer.pass.cpp | 14 +- .../get_unsigned_int.pass.cpp | 20 +- .../get_unsigned_long.pass.cpp | 20 +- .../get_unsigned_long_long.pass.cpp | 20 +- .../get_unsigned_short.pass.cpp | 20 +- .../test_min_max.pass.cpp | 17 +- .../test_neg_one.pass.cpp | 40 +- .../category.numeric/nothing_to_do.pass.cpp | 13 - .../date_order.pass.cpp | 2 +- .../date_order_wide.pass.cpp | 4 +- .../locale.time.get.byname/get_date.pass.cpp | 5 +- .../get_date_wide.pass.cpp | 7 +- .../get_monthname.pass.cpp | 4 +- .../get_monthname_wide.pass.cpp | 3 +- .../locale.time.get.byname/get_one.pass.cpp | 7 +- .../get_one_wide.pass.cpp | 9 +- .../locale.time.get.byname/get_time.pass.cpp | 3 +- .../get_time_wide.pass.cpp | 5 +- .../get_weekday.pass.cpp | 6 +- .../get_weekday_wide.pass.cpp | 6 +- .../locale.time.get.byname/get_year.pass.cpp | 3 +- .../get_year_wide.pass.cpp | 5 +- .../date_order.pass.cpp | 2 +- .../locale.time.get.members/get_date.pass.cpp | 3 +- .../get_date_wide.pass.cpp | 5 +- .../locale.time.get.members/get_many.pass.cpp | 3 +- .../get_monthname.pass.cpp | 2 +- .../get_monthname_wide.pass.cpp | 4 +- .../locale.time.get.members/get_one.pass.cpp | 2 +- .../locale.time.get.members/get_time.pass.cpp | 2 +- .../get_time_wide.pass.cpp | 4 +- .../get_weekday.pass.cpp | 2 +- .../get_weekday_wide.pass.cpp | 4 +- .../locale.time.get.members/get_year.pass.cpp | 3 +- .../locale.time.put.byname/put1.pass.cpp | 13 +- .../locale.time.put.members/put1.pass.cpp | 1 + .../locale.time.put.members/put2.pass.cpp | 4 + .../category.time/nothing_to_do.pass.cpp | 13 - .../decimal_point.pass.cpp | 6 + .../locale.numpunct.byname/grouping.pass.cpp | 9 + .../thousands_sep.pass.cpp | 42 +- .../locale.numpunct/ctor.pass.cpp | 3 + .../decimal_point.pass.cpp | 2 + .../facet.numpunct.members/falsename.pass.cpp | 2 + .../facet.numpunct.members/grouping.pass.cpp | 2 + .../thousands_sep.pass.cpp | 2 + .../facet.numpunct.members/truename.pass.cpp | 2 + .../locale.numpunct/types.pass.cpp | 2 + .../facet.numpunct/nothing_to_do.pass.cpp | 13 - .../locale.stdcvt/codecvt_utf16.pass.cpp | 3 + .../codecvt_utf16_always_noconv.pass.cpp | 2 + .../codecvt_utf16_encoding.pass.cpp | 2 + .../codecvt_utf16_length.pass.cpp | 643 +- .../codecvt_utf16_max_length.pass.cpp | 88 +- .../locale.stdcvt/codecvt_utf16_out.pass.cpp | 2 + .../codecvt_utf16_unshift.pass.cpp | 2 + .../locale.stdcvt/codecvt_utf8.pass.cpp | 3 + .../codecvt_utf8_always_noconv.pass.cpp | 2 + .../codecvt_utf8_encoding.pass.cpp | 2 + .../codecvt_utf8_length.pass.cpp | 344 +- .../codecvt_utf8_max_length.pass.cpp | 88 +- .../locale.stdcvt/codecvt_utf8_out.pass.cpp | 2 + .../codecvt_utf8_unshift.pass.cpp | 2 + .../codecvt_utf8_utf16_always_noconv.pass.cpp | 2 + .../codecvt_utf8_utf16_encoding.pass.cpp | 2 + .../codecvt_utf8_utf16_in.pass.cpp | 2 +- .../codecvt_utf8_utf16_length.pass.cpp | 2 + .../codecvt_utf8_utf16_max_length.pass.cpp | 2 + .../codecvt_utf8_utf16_out.pass.cpp | 2 +- .../codecvt_utf8_utf16_unshift.pass.cpp | 2 + .../conversions.buffer/ctor.pass.cpp | 24 +- .../conversions.buffer/lit.local.cfg | 2 - .../conversions.buffer/overflow.pass.cpp | 2 + .../conversions.buffer/pbackfail.pass.cpp | 4 + .../conversions.buffer/rdbuf.pass.cpp | 2 + .../conversions.buffer/seekoff.pass.cpp | 2 + .../conversions.buffer/state.pass.cpp | 2 + .../conversions.buffer/test.pass.cpp | 2 + .../conversions.buffer/underflow.pass.cpp | 4 + .../conversions.string/converted.pass.cpp | 2 + .../conversions.string/ctor_codecvt.pass.cpp | 21 +- .../ctor_codecvt_state.pass.cpp | 2 + .../conversions.string/ctor_copy.pass.cpp | 4 +- .../ctor_err_string.pass.cpp | 2 + .../conversions.string/from_bytes.pass.cpp | 2 + .../conversions.string/state.pass.cpp | 2 + .../conversions.string/to_bytes.pass.cpp | 2 + .../conversions.string/types.pass.cpp | 2 + .../conversions/nothing_to_do.pass.cpp | 13 - .../locale.convenience/nothing_to_do.pass.cpp | 13 - .../locale/locale.cons/assign.pass.cpp | 67 +- .../locale/locale.cons/char_pointer.pass.cpp | 66 +- .../locales/locale/locale.cons/copy.pass.cpp | 67 +- .../locale/locale.cons/default.pass.cpp | 67 +- .../locale_char_pointer_cat.pass.cpp | 68 +- .../locale.cons/locale_facetptr.pass.cpp | 67 +- .../locale.cons/locale_locale_cat.pass.cpp | 68 +- .../locale.cons/locale_string_cat.pass.cpp | 67 +- .../locale/locale.cons/string.pass.cpp | 67 +- .../locale/locale.members/combine.pass.cpp | 68 +- .../locale/locale.operators/compare.pass.cpp | 5 + .../locale/locale.statics/classic.pass.cpp | 67 +- .../locale/locale.statics/global.pass.cpp | 67 +- .../locale.category/category.pass.cpp | 5 - .../locale.types/nothing_to_do.pass.cpp | 13 - .../locales/locale/nothing_to_do.pass.cpp | 13 - .../locales/nothing_to_do.pass.cpp | 13 - .../namespace/addressable_functions.sh.cpp | 206 + test/std/nothing_to_do.pass.cpp | 14 - .../bit/bit.cast/bit_cast.compile.pass.cpp | 63 + .../numerics/bit/bit.cast/bit_cast.pass.cpp | 257 + .../numerics/bit/bit.endian/endian.pass.cpp | 2 +- .../bit/bit.pow.two/bit_ceil.fail.cpp | 52 + .../bit/bit.pow.two/bit_ceil.pass.cpp | 143 + .../bit/bit.pow.two/bit_floor.pass.cpp | 141 + .../bit/bit.pow.two/bit_width.pass.cpp | 144 + .../numerics/bit/bit.pow.two/ceil2.fail.cpp | 50 - .../numerics/bit/bit.pow.two/ceil2.pass.cpp | 148 - .../numerics/bit/bit.pow.two/floor2.pass.cpp | 164 - .../bit/bit.pow.two/has_single_bit.pass.cpp | 142 + .../numerics/bit/bit.pow.two/ispow2.pass.cpp | 162 - .../numerics/bit/bit.pow.two/log2p1.pass.cpp | 177 - .../bit/bitops.count/countl_one.pass.cpp | 227 +- .../bit/bitops.count/countl_zero.pass.cpp | 230 +- .../bit/bitops.count/countr_one.pass.cpp | 231 +- .../bit/bitops.count/countr_zero.pass.cpp | 229 +- .../bit/bitops.count/popcount.pass.cpp | 241 +- .../std/numerics/bit/bitops.rot/rotl.pass.cpp | 229 +- .../std/numerics/bit/bitops.rot/rotr.pass.cpp | 246 +- test/std/numerics/bit/byteswap.pass.cpp | 102 + test/std/numerics/bit/nothing_to_do.pass.cpp | 12 - test/std/numerics/c.math/abs.fail.cpp | 32 - test/std/numerics/c.math/abs.pass.cpp | 14 +- test/std/numerics/c.math/abs.verify.cpp | 26 + .../c.math/c.math.lerp/c.math.lerp.pass.cpp | 75 - test/std/numerics/c.math/cmath.pass.cpp | 85 +- test/std/numerics/c.math/lerp.pass.cpp | 74 + .../numerics/cfenv/cfenv.syn/cfenv.pass.cpp | 2 - test/std/numerics/complex.number/cases.h | 20 +- .../complex.number/cmplx.over/arg.pass.cpp | 2 + .../complex.number/cmplx.over/pow.pass.cpp | 2 + .../complex.literals/literals.pass.cpp | 2 +- .../literals1.compile.fail.cpp | 20 + .../complex.literals/literals1.fail.cpp | 21 - .../complex.literals/literals1.pass.cpp | 2 +- .../complex.literals/literals2.pass.cpp | 4 +- .../complex_not_equals_scalar.pass.cpp | 2 +- .../complex.ops/stream_input.pass.cpp | 2 + .../complex.ops/stream_output.pass.cpp | 124 +- ...ble_long_double_implicit.compile.fail.cpp} | 0 ...=> float_double_implicit.compile.fail.cpp} | 0 ...oat_long_double_implicit.compile.fail.cpp} | 0 .../complex.transcendentals/acos.pass.cpp | 2 + .../complex.transcendentals/acosh.pass.cpp | 2 + .../complex.transcendentals/asin.pass.cpp | 2 + .../complex.transcendentals/asinh.pass.cpp | 2 + .../complex.transcendentals/atan.pass.cpp | 2 + .../complex.transcendentals/atanh.pass.cpp | 2 + .../complex.transcendentals/exp.pass.cpp | 6 +- .../complex.transcendentals/log.pass.cpp | 2 + .../complex.transcendentals/log10.pass.cpp | 2 + .../pow_complex_complex.pass.cpp | 2 + .../pow_complex_scalar.pass.cpp | 2 + .../pow_scalar_complex.pass.cpp | 2 + .../complex.transcendentals/sqrt.pass.cpp | 2 + .../complex.transcendentals/tanh.pass.cpp | 8 +- .../complex.value.ops/arg.pass.cpp | 2 + test/std/numerics/nothing_to_do.pass.cpp | 13 - .../class.gslice/nothing_to_do.pass.cpp | 13 - .../class.slice/nothing_to_do.pass.cpp | 13 - ...ault.fail.cpp => default.compile.fail.cpp} | 0 ...ault.fail.cpp => default.compile.fail.cpp} | 0 ...ault.fail.cpp => default.compile.fail.cpp} | 0 ...ault.fail.cpp => default.compile.fail.cpp} | 0 .../slice.arr.assign/template.pass.cpp | 33 + .../slice.arr.assign/valarray.pass.cpp | 19 +- .../initializer_list_assign.pass.cpp | 2 +- .../valarray.assign/move_assign.pass.cpp | 2 +- .../value_assign.addressof.compile.pass.cpp | 26 + .../valarray.cons/deduct.pass.cpp | 73 + .../valarray.cons/initializer_list.pass.cpp | 2 +- .../valarray.cons/move.pass.cpp | 2 +- .../valarray.members/max.pass.cpp | 5 - .../valarray.members/min.pass.cpp | 5 - .../valarray.unary/not.pass.cpp | 2 +- .../nothing_to_do.pass.cpp | 13 - .../and_valarray_valarray.pass.cpp | 11 +- .../and_valarray_value.pass.cpp | 20 +- .../and_value_valarray.pass.cpp | 20 +- .../equal_valarray_valarray.pass.cpp | 11 +- .../equal_valarray_value.pass.cpp | 10 +- .../equal_value_valarray.pass.cpp | 10 +- .../greater_equal_valarray_valarray.pass.cpp | 11 +- .../greater_equal_valarray_value.pass.cpp | 10 +- .../greater_equal_value_valarray.pass.cpp | 10 +- .../greater_valarray_valarray.pass.cpp | 11 +- .../greater_valarray_value.pass.cpp | 10 +- .../greater_value_valarray.pass.cpp | 10 +- .../less_equal_valarray_valarray.pass.cpp | 11 +- .../less_equal_valarray_value.pass.cpp | 10 +- .../less_equal_value_valarray.pass.cpp | 10 +- .../less_valarray_valarray.pass.cpp | 11 +- .../less_valarray_value.pass.cpp | 10 +- .../less_value_valarray.pass.cpp | 10 +- .../not_equal_valarray_valarray.pass.cpp | 11 +- .../not_equal_valarray_value.pass.cpp | 10 +- .../not_equal_value_valarray.pass.cpp | 10 +- .../or_valarray_valarray.pass.cpp | 11 +- .../or_valarray_value.pass.cpp | 20 +- .../or_value_valarray.pass.cpp | 20 +- .../valarray.transcend/acos_valarray.pass.cpp | 14 +- .../valarray.transcend/asin_valarray.pass.cpp | 14 +- .../atan2_valarray_valarray.pass.cpp | 14 +- .../atan2_valarray_value.pass.cpp | 14 +- .../atan2_value_valarray.pass.cpp | 14 +- .../valarray.transcend/atan_valarray.pass.cpp | 14 +- .../valarray.transcend/cos_valarray.pass.cpp | 14 +- .../valarray.transcend/cosh_valarray.pass.cpp | 14 +- .../valarray.transcend/exp_valarray.pass.cpp | 14 +- .../log10_valarray.pass.cpp | 14 +- .../valarray.transcend/log_valarray.pass.cpp | 14 +- .../pow_valarray_valarray.pass.cpp | 14 +- .../pow_valarray_value.pass.cpp | 14 +- .../pow_value_valarray.pass.cpp | 14 +- .../valarray.transcend/sin_valarray.pass.cpp | 14 +- .../valarray.transcend/sinh_valarray.pass.cpp | 14 +- .../valarray.transcend/sqrt_valarray.pass.cpp | 14 +- .../valarray.transcend/tan_valarray.pass.cpp | 14 +- .../valarray.transcend/tanh_valarray.pass.cpp | 14 +- .../valarray.transcend/valarray_helper.h | 18 + test/std/numerics/numbers/defined.pass.cpp | 79 + .../std/numerics/numbers/illformed.verify.cpp | 29 + test/std/numerics/numbers/specialize.pass.cpp | 80 + test/std/numerics/numbers/user_type.pass.cpp | 57 + test/std/numerics/numbers/value.pass.cpp | 89 + .../accumulate/accumulate.pass.cpp | 21 +- .../accumulate/accumulate_op.pass.cpp | 85 +- .../adjacent_difference.pass.cpp | 45 +- .../adjacent_difference_op.pass.cpp | 115 +- .../exclusive.scan/exclusive_scan.pass.cpp | 67 +- .../exclusive_scan_init_op.pass.cpp | 60 +- .../inclusive.scan/inclusive_scan.pass.cpp | 70 +- .../inclusive.scan/inclusive_scan_op.pass.cpp | 83 +- .../inclusive_scan_op_init.pass.cpp | 78 +- .../inner.product/inner_product.pass.cpp | 37 +- .../inner.product/inner_product_comp.pass.cpp | 111 +- .../numeric.ops/numeric.iota/iota.pass.cpp | 17 +- .../gcd.bool1.compile.fail.cpp | 26 + .../numeric.ops.gcd/gcd.bool1.fail.cpp | 26 - .../gcd.bool2.compile.fail.cpp | 26 + .../numeric.ops.gcd/gcd.bool2.fail.cpp | 26 - .../gcd.bool3.compile.fail.cpp | 26 + .../numeric.ops.gcd/gcd.bool3.fail.cpp | 26 - .../gcd.bool4.compile.fail.cpp | 26 + .../numeric.ops.gcd/gcd.bool4.fail.cpp | 26 - .../gcd.not_integral1.compile.fail.cpp | 26 + .../gcd.not_integral1.fail.cpp | 26 - .../gcd.not_integral2.compile.fail.cpp | 26 + .../gcd.not_integral2.fail.cpp | 26 - .../numeric.ops/numeric.ops.gcd/gcd.pass.cpp | 7 +- .../lcm.bool1.compile.fail.cpp | 26 + .../numeric.ops.lcm/lcm.bool1.fail.cpp | 26 - .../lcm.bool2.compile.fail.cpp | 26 + .../numeric.ops.lcm/lcm.bool2.fail.cpp | 26 - .../lcm.bool3.compile.fail.cpp | 26 + .../numeric.ops.lcm/lcm.bool3.fail.cpp | 26 - .../lcm.bool4.compile.fail.cpp | 26 + .../numeric.ops.lcm/lcm.bool4.fail.cpp | 26 - .../lcm.not_integral1.compile.fail.cpp | 26 + .../lcm.not_integral1.fail.cpp | 26 - .../lcm.not_integral2.compile.fail.cpp | 26 + .../lcm.not_integral2.fail.cpp | 26 - .../numeric.ops/numeric.ops.lcm/lcm.pass.cpp | 7 +- .../numeric.ops.midpoint/midpoint.fail.cpp | 4 +- .../midpoint.float.pass.cpp | 7 +- .../midpoint.integer.pass.cpp | 12 +- .../midpoint.pointer.pass.cpp | 2 +- .../partial.sum/partial_sum.pass.cpp | 27 +- .../partial.sum/partial_sum_op.pass.cpp | 98 +- .../numeric.ops/reduce/reduce.pass.cpp | 29 +- .../numeric.ops/reduce/reduce_init.pass.cpp | 29 +- .../reduce/reduce_init_op.pass.cpp | 29 +- ...sform_exclusive_scan_init_bop_uop.pass.cpp | 78 +- .../transform_inclusive_scan_bop_uop.pass.cpp | 78 +- ...sform_inclusive_scan_bop_uop_init.pass.cpp | 80 +- ...orm_reduce_iter_iter_init_bop_uop.pass.cpp | 32 +- ...nsform_reduce_iter_iter_iter_init.pass.cpp | 44 +- ..._reduce_iter_iter_iter_init_op_op.pass.cpp | 44 +- test/std/numerics/rand/nothing_to_do.pass.cpp | 13 - .../rand/rand.adapt/nothing_to_do.pass.cpp | 13 - .../rand.adapt.disc/ctor_result_type.pass.cpp | 3 + .../rand.adapt.disc/ctor_sseq.pass.cpp | 3 + .../rand.adapt/rand.adapt.disc/io.pass.cpp | 2 + .../ctor_result_type.pass.cpp | 3 + .../rand.adapt.ibits/ctor_sseq.pass.cpp | 3 + .../rand.adapt/rand.adapt.ibits/io.pass.cpp | 2 + .../rand.adapt.shuf/ctor_result_type.pass.cpp | 3 + .../rand.adapt.shuf/ctor_sseq.pass.cpp | 3 + .../rand.adapt/rand.adapt.shuf/io.pass.cpp | 2 + .../numerics/rand/rand.device/ctor.pass.cpp | 73 +- .../rand/rand.device/entropy.pass.cpp | 13 +- .../numerics/rand/rand.device/eval.pass.cpp | 23 +- .../rand/rand.dis/nothing_to_do.pass.cpp | 13 - .../rand.dist.bern/nothing_to_do.pass.cpp | 13 - .../ctor_double.pass.cpp | 19 +- .../rand.dist.bern.bernoulli/io.pass.cpp | 2 + .../ctor_int_double.pass.cpp | 24 +- .../rand.dist.bern.bin/eval.PR44847.pass.cpp | 166 + .../rand.dist.bern.bin/eval.pass.cpp | 99 +- .../rand.dist.bern.bin/io.pass.cpp | 2 + .../rand.dist.bern.geo/ctor_double.pass.cpp | 23 +- .../rand.dist.bern.geo/eval.pass.cpp | 11 + .../rand.dist.bern.geo/io.pass.cpp | 2 + .../ctor_int_double.pass.cpp | 24 +- .../rand.dist.bern.negbin/eval.pass.cpp | 10 +- .../rand.dist.bern.negbin/io.pass.cpp | 2 + .../rand.dist.norm/nothing_to_do.pass.cpp | 13 - .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.norm.cauchy/io.pass.cpp | 2 + .../rand.dist.norm.chisq/ctor_double.pass.cpp | 23 +- .../rand.dist.norm.chisq/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.norm.f/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../eval_param.PR52906.pass.cpp | 38 + .../rand.dist.norm.lognormal/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.norm.normal/io.pass.cpp | 2 + .../rand.dist.norm.t/ctor_double.pass.cpp | 23 +- .../rand.dist.norm.t/io.pass.cpp | 2 + .../rand.dist.pois/nothing_to_do.pass.cpp | 13 - .../rand.dist.pois.exp/ctor_double.pass.cpp | 23 +- .../rand.dist.pois.exp/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.pois.extreme/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.pois.gamma/io.pass.cpp | 2 + .../ctor_double.pass.cpp | 23 +- .../rand.dist.pois.poisson/eval.pass.cpp | 64 +- .../rand.dist.pois.poisson/io.pass.cpp | 2 + .../ctor_double_double.pass.cpp | 24 +- .../rand.dist.pois.weibull/io.pass.cpp | 2 + .../rand.dist.samp/nothing_to_do.pass.cpp | 13 - .../ctor_init.pass.cpp | 2 +- .../rand.dist.samp.discrete/io.pass.cpp | 2 + .../param_ctor_default.pass.cpp | 2 +- .../param_ctor_init.pass.cpp | 2 +- .../ctor_default.pass.cpp | 2 +- .../ctor_init_func.pass.cpp | 2 +- .../rand.dist.samp.pconst/io.pass.cpp | 2 + .../param_ctor_init_func.pass.cpp | 2 +- .../ctor_default.pass.cpp | 2 +- .../ctor_init_func.pass.cpp | 2 +- .../rand.dist.samp.plinear/io.pass.cpp | 2 + .../param_ctor_init_func.pass.cpp | 2 +- .../rand.dist.uni/nothing_to_do.pass.cpp | 13 - .../rand.dist.uni.int/ctor_int_int.pass.cpp | 25 +- .../rand.dist.uni.int/eval.pass.cpp | 542 +- .../rand.dist.uni.int/int128.pass.cpp | 86 + .../rand.dist.uni.int/io.pass.cpp | 2 + .../rand.dist.uni.real/ctor_int_int.pass.cpp | 44 - .../ctor_real_real.pass.cpp | 64 + .../rand.dist.uni.real/io.pass.cpp | 2 + .../rand/rand.eng/nothing_to_do.pass.cpp | 13 - .../rand/rand.eng/rand.eng.lcong/alg.pass.cpp | 69 + .../rand.eng.lcong/ctor_result_type.pass.cpp | 80 +- .../rand/rand.eng/rand.eng.lcong/io.pass.cpp | 2 + .../rand.eng/rand.eng.lcong/params.fail.cpp | 31 + .../rand.eng/rand.eng.lcong/values.pass.cpp | 8 +- .../rand.eng.mers/ctor_result_type.pass.cpp | 42 +- .../rand.eng/rand.eng.mers/ctor_sseq.pass.cpp | 3 + .../rand.eng.mers/ctor_sseq_all_zero.pass.cpp | 3 - .../rand.eng/rand.eng.mers/default.pass.cpp | 1 - .../rand.eng/rand.eng.mers/discard.pass.cpp | 1 - .../rand/rand.eng/rand.eng.mers/eval.pass.cpp | 1 - .../rand/rand.eng/rand.eng.mers/io.pass.cpp | 2 + .../rand.eng.sub/ctor_result_type.pass.cpp | 44 +- .../rand.eng/rand.eng.sub/ctor_sseq.pass.cpp | 3 + .../rand/rand.eng/rand.eng.sub/io.pass.cpp | 2 + .../rand/rand.req/nothing_to_do.pass.cpp | 13 - .../rand.req.urng/nothing_to_do.pass.cpp | 13 - ...form_random_bit_generator.compile.pass.cpp | 145 + .../rand/rand.util/nothing_to_do.pass.cpp | 13 - ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../rand.util.seedseq/default.pass.cpp | 3 + .../initializer_list.pass.cpp | 2 +- .../rand.util.seedseq/iterator.pass.cpp | 42 +- .../rand.util.seedseq/iterator.verify.cpp | 30 + test/std/ranges/range.access/begin.pass.cpp | 343 + test/std/ranges/range.access/data.pass.cpp | 292 + test/std/ranges/range.access/empty.pass.cpp | 188 + test/std/ranges/range.access/end.pass.cpp | 376 + test/std/ranges/range.access/size.pass.cpp | 336 + test/std/ranges/range.access/ssize.pass.cpp | 92 + .../range.adaptors/range.all/all.pass.cpp | 194 + .../range.all/all_t.compile.pass.cpp | 64 + .../range.all/range.owning.view/base.pass.cpp | 61 + .../range.owning.view/begin_end.pass.cpp | 133 + .../borrowing.compile.pass.cpp | 21 + .../range.owning.view/constructor.pass.cpp | 140 + .../range.all/range.owning.view/data.pass.cpp | 78 + .../range.owning.view/empty.pass.cpp | 105 + .../range.all/range.owning.view/size.pass.cpp | 99 + .../range.ref.view/borrowing.compile.pass.cpp | 22 + .../range.ref.view/range.ref.view.pass.cpp | 210 + .../range.common.view/adaptor.pass.cpp | 116 + .../range.common.view/base.pass.cpp | 70 + .../range.common.view/begin.pass.cpp | 93 + .../borrowing.compile.pass.cpp | 26 + .../range.common.view/ctad.compile.pass.cpp | 67 + .../range.common.view/ctor.default.pass.cpp | 32 + .../range.common.view/ctor.view.pass.cpp | 54 + .../range.common.view/end.pass.cpp | 86 + .../range.common.view/size.pass.cpp | 53 + .../range.adaptors/range.common.view/types.h | 93 + .../range.counted/counted.pass.cpp | 241 + .../range.adaptors/range.drop/base.pass.cpp | 45 + .../range.adaptors/range.drop/begin.pass.cpp | 124 + .../range.drop/ctad.compile.pass.cpp | 66 + .../range.drop/ctor.default.pass.cpp | 39 + .../range.drop/ctor.view.pass.cpp | 36 + .../range.drop/dangling.cache.pass.cpp | 56 + .../range.adaptors/range.drop/end.pass.cpp | 52 + .../range.drop/general.pass.cpp | 94 + .../range.adaptors/range.drop/size.pass.cpp | 54 + .../ranges/range.adaptors/range.drop/types.h | 97 + .../range.empty/borrowing.compile.pass.cpp | 23 + .../range.empty/empty_view.pass.cpp | 68 + .../range.join.view/base.pass.cpp | 62 + .../range.join.view/begin.pass.cpp | 122 + .../range.join.view/ctad.compile.pass.cpp | 69 + .../range.join.view/ctad.verify.cpp | 33 + .../range.join.view/ctor.default.pass.cpp | 37 + .../range.join.view/ctor.view.pass.cpp | 49 + .../range.join.view/end.pass.cpp | 120 + .../range.join.view/general.pass.cpp | 51 + .../range.join.view/iterator/arrow.pass.cpp | 50 + .../iterator/ctor.default.pass.cpp | 57 + .../iterator/ctor.other.pass.cpp | 41 + .../iterator/ctor.parent.outer.pass.cpp | 38 + .../iterator/decrement.pass.cpp | 74 + .../range.join.view/iterator/eq.pass.cpp | 41 + .../iterator/increment.pass.cpp | 160 + .../iterator/iter.move.pass.cpp | 38 + .../iterator/iter.swap.pass.cpp | 43 + .../iterator/member_types.compile.pass.cpp | 63 + .../range.join.view/iterator/star.pass.cpp | 55 + .../sentinel/ctor.default.pass.cpp | 33 + .../sentinel/ctor.other.pass.cpp | 41 + .../sentinel/ctor.parent.pass.cpp | 45 + .../range.join.view/sentinel/eq.pass.cpp | 52 + .../range.adaptors/range.join.view/types.h | 141 + .../range.reverse/adaptor.pass.cpp | 181 + .../range.reverse/base.pass.cpp | 84 + .../range.reverse/begin.pass.cpp | 154 + .../range.reverse/borrowing.compile.pass.cpp | 21 + .../range.reverse/ctad.compile.pass.cpp | 69 + .../range.reverse/ctor.default.pass.cpp | 58 + .../range.reverse/ctor.view.pass.cpp | 63 + .../range.adaptors/range.reverse/end.pass.cpp | 70 + ...range_concept_conformance.compile.pass.cpp | 28 + .../range.reverse/size.pass.cpp | 83 + .../range.adaptors/range.reverse/types.h | 60 + .../range.adaptors/range.take/base.pass.cpp | 66 + .../range.adaptors/range.take/begin.pass.cpp | 89 + .../range.take/borrowing.compile.pass.cpp | 21 + .../range.take/ctad.compile.pass.cpp | 66 + .../range.take/ctor.default.pass.cpp | 56 + .../range.take/ctor.view_count.pass.cpp | 52 + .../range.adaptors/range.take/end.pass.cpp | 82 + ...range_concept_conformance.compile.pass.cpp | 27 + .../range.take/sentinel/base.pass.cpp | 42 + .../range.take/sentinel/ctor.pass.cpp | 73 + .../range.take/sentinel/eq.pass.cpp | 57 + .../range.adaptors/range.take/size.pass.cpp | 83 + .../ranges/range.adaptors/range.take/types.h | 57 + .../range.transform/adaptor.pass.cpp | 151 + .../range.transform/base.pass.cpp | 59 + .../range.transform/begin.pass.cpp | 62 + .../range.transform/ctad.compile.pass.cpp | 71 + .../range.transform/ctor.default.pass.cpp | 78 + .../ctor.view_function.pass.cpp | 64 + .../range.transform/end.pass.cpp | 125 + .../range.transform/general.pass.cpp | 94 + .../iterator/arithmetic.pass.cpp | 48 + .../range.transform/iterator/base.pass.cpp | 55 + .../range.transform/iterator/compare.pass.cpp | 75 + .../range.transform/iterator/ctor.pass.cpp | 79 + .../range.transform/iterator/deref.pass.cpp | 63 + .../iterator/iter_move.pass.cpp | 51 + .../iterator/plus_minus.pass.cpp | 41 + .../iterator/requirements.compile.pass.cpp | 24 + .../iterator/sentinel.pass.cpp | 65 + .../iterator/subscript.pass.cpp | 50 + .../range.transform/iterator/types.pass.cpp | 93 + .../range.transform/size.pass.cpp | 48 + .../range.adaptors/range.transform/types.h | 150 + .../range.iota.view/begin.pass.cpp | 61 + .../borrowing.compile.pass.cpp | 21 + .../range.iota.view/ctad.compile.pass.cpp | 54 + .../range.iota.view/ctor.default.pass.cpp | 38 + .../range.iota.view/ctor.first.last.pass.cpp | 49 + .../range.iota.view/ctor.value.bound.pass.cpp | 64 + .../range.iota.view/ctor.value.pass.cpp | 72 + .../range.iota.view/end.pass.cpp | 87 + .../range.iota.view/iterator/compare.pass.cpp | 96 + .../iterator/ctor.default.pass.cpp | 34 + .../iterator/ctor.value.pass.cpp | 46 + .../iterator/decrement.pass.cpp | 67 + .../iterator/increment.pass.cpp | 70 + .../iterator/member_typedefs.compile.pass.cpp | 163 + .../range.iota.view/iterator/minus.pass.cpp | 179 + .../iterator/minus_eq.pass.cpp | 91 + .../range.iota.view/iterator/plus.pass.cpp | 88 + .../range.iota.view/iterator/plus_eq.pass.cpp | 91 + .../range.iota.view/iterator/star.pass.cpp | 111 + .../iterator/subscript.pass.cpp | 67 + ...range_concept_conformance.compile.pass.cpp | 44 + .../sentinel/ctor.default.pass.cpp | 34 + .../sentinel/ctor.value.pass.cpp | 48 + .../range.iota.view/sentinel/eq.pass.cpp | 59 + .../range.iota.view/sentinel/minus.pass.cpp | 65 + .../range.iota.view/size.pass.cpp | 102 + .../range.iota.view/type.compile.pass.cpp | 22 + .../range.factories/range.iota.view/types.h | 212 + .../range.iota.view/views_iota.pass.cpp | 81 + .../range.single.view/assign.pass.cpp | 44 + .../range.single.view/begin.pass.cpp | 74 + .../borrowing.compile.pass.cpp | 22 + .../range.single.view/ctad.compile.pass.cpp | 38 + .../range.single.view/ctor.default.pass.cpp | 50 + .../range.single.view/ctor.in_place.pass.cpp | 49 + .../range.single.view/ctor.value.pass.cpp | 59 + .../range.single.view/data.pass.cpp | 74 + .../range.single.view/end.pass.cpp | 74 + ...range_concept_conformance.compile.pass.cpp | 31 + .../range.single.view/size.pass.cpp | 66 + .../borrowed_range.compile.pass.cpp | 62 + ...orrowed_range.subsumption.compile.pass.cpp | 27 + .../enable_borrowed_range.compile.pass.cpp | 67 + .../helper_aliases.compile.pass.cpp | 37 + .../range.range/iterator_t.compile.pass.cpp | 32 + .../range.range/range.compile.pass.cpp | 53 + .../range.range/range_size_t.compile.pass.cpp | 42 + .../range.range/sentinel_t.compile.pass.cpp | 30 + .../bidirectional_range.compile.pass.cpp | 56 + .../common_range.compile.pass.cpp | 83 + .../contiguous_range.compile.pass.cpp | 95 + .../forward_range.compile.pass.cpp | 57 + .../input_range.compile.pass.cpp | 61 + .../output_range.compile.pass.cpp | 66 + .../random_access_range.compile.pass.cpp | 58 + .../subsumption.compile.pass.cpp | 94 + .../viewable_range.compile.pass.cpp | 186 + .../range.sized/sized_range.compile.pass.cpp | 79 + .../range.sized/subsumption.compile.pass.cpp | 28 + .../range.view/enable_view.compile.pass.cpp | 105 + .../range.view/view.compile.pass.cpp | 94 + .../view.subsumption.compile.pass.cpp | 46 + .../range.view/view_base.compile.pass.cpp | 25 + .../borrowed_iterator.compile.pass.cpp | 36 + .../borrowed_subrange.compile.pass.cpp | 44 + .../range.dangling/dangling.pass.cpp | 40 + .../range.subrange/advance.pass.cpp | 59 + .../range.subrange/borrowing.compile.pass.cpp | 20 + .../range.subrange/ctad.compile.pass.cpp | 51 + .../range.subrange/ctor.begin_end.pass.cpp | 53 + .../ctor.begin_end_size.pass.cpp | 60 + .../range.subrange/ctor.default.pass.cpp | 69 + .../ctor.pair_like_conv.pass.cpp | 49 + .../range.subrange/ctor.range.pass.cpp | 51 + .../range.subrange/ctor.range_size.pass.cpp | 79 + .../range.subrange/general.compile.pass.cpp | 41 + .../range.utility/range.subrange/get.pass.cpp | 98 + .../range.subrange/lwg3470.pass.cpp | 50 + .../range.subrange/primitives.pass.cpp | 67 + .../structured_bindings.pass.cpp | 113 + .../range.utility/range.subrange/types.h | 224 + .../view.interface/view.interface.pass.cpp | 329 + test/std/re/lit.local.cfg | 3 + test/std/re/nothing_to_do.pass.cpp | 13 - test/std/re/re.alg/nothing_to_do.pass.cpp | 13 - .../re.alg/re.alg.match/awk.locale.pass.cpp | 120 + test/std/re/re.alg/re.alg.match/awk.pass.cpp | 92 +- ...{basic.fail.cpp => basic.compile.fail.cpp} | 0 .../re.alg/re.alg.match/basic.locale.pass.cpp | 123 + .../std/re/re.alg/re.alg.match/basic.pass.cpp | 94 +- .../re.alg/re.alg.match/ecma.locale.pass.cpp | 119 + test/std/re/re.alg/re.alg.match/ecma.pass.cpp | 89 +- .../re.alg/re.alg.match/exponential.pass.cpp | 4 +- .../re.alg.match/extended.locale.pass.cpp | 123 + .../re/re.alg/re.alg.match/extended.pass.cpp | 130 +- .../inverted_character_classes.pass.cpp | 2 +- .../parse_curly_brackets.pass.cpp | 2 +- .../re.alg.replace/exponential.pass.cpp | 2 +- .../re.alg/re.alg.search/awk.locale.pass.cpp | 123 + test/std/re/re.alg/re.alg.search/awk.pass.cpp | 94 +- .../re/re.alg/re.alg.search/backup.pass.cpp | 2 +- ...{basic.fail.cpp => basic.compile.fail.cpp} | 0 .../re.alg.search/basic.locale.pass.cpp | 123 + .../re/re.alg/re.alg.search/basic.pass.cpp | 94 +- .../re.alg/re.alg.search/ecma.locale.pass.cpp | 119 + .../std/re/re.alg/re.alg.search/ecma.pass.cpp | 89 +- .../re.alg/re.alg.search/exponential.pass.cpp | 4 +- .../re.alg.search/extended.locale.pass.cpp | 123 + .../re/re.alg/re.alg.search/extended.pass.cpp | 129 +- .../re.alg/re.alg.search/lookahead.pass.cpp | 2 +- test/std/re/re.badexp/regex_error.pass.cpp | 1 - test/std/re/re.const/nothing_to_do.pass.cpp | 14 - .../re/re.const/re.err/error_type.pass.cpp | 1 - .../re.matchflag/match_flag_type.pass.cpp | 1 - .../re.matchflag/match_multiline.pass.cpp | 271 + .../re.matchflag/match_not_bol.pass.cpp | 1 - .../re.matchflag/match_not_eol.pass.cpp | 1 - .../re.matchflag/match_prev_avail.pass.cpp | 84 + .../re.synopt/syntax_option_type.pass.cpp | 18 +- .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - .../nothing_to_do.pass.cpp | 1 - test/std/re/re.def/nothing_to_do.pass.cpp | 14 - test/std/re/re.general/nothing_to_do.pass.cpp | 1 - .../re.grammar/excessive_brace_count.pass.cpp | 4 +- .../excessive_brace_min_max.pass.cpp | 4 +- test/std/re/re.grammar/nothing_to_do.pass.cpp | 13 - test/std/re/re.iter/nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 25 + ...{cnstr.fail.cpp => cnstr.compile.fail.cpp} | 0 .../re.regiter.cnstr/default.pass.cpp | 2 + .../re.regiter/re.regiter.incr/post.pass.cpp | 2 +- test/std/re/re.iter/re.regiter/types.pass.cpp | 2 + ...rator_concept_conformance.compile.pass.cpp | 25 + ...{array.fail.cpp => array.compile.fail.cpp} | 0 .../{init.fail.cpp => init.compile.fail.cpp} | 0 .../re.tokiter/re.tokiter.cnstr/init.pass.cpp | 2 +- .../{int.fail.cpp => int.compile.fail.cpp} | 0 ...ector.fail.cpp => vector.compile.fail.cpp} | 0 .../re.regex.assign/assign.il.pass.cpp | 2 +- .../assign_iter_iter_flag.pass.cpp | 2 +- .../re/re.regex/re.regex.assign/il.pass.cpp | 2 +- .../re.regex.construct/bad_backref.pass.cpp | 60 +- .../re.regex.construct/bad_ctype.pass.cpp | 2 +- .../re.regex.construct/bad_escape.pass.cpp | 2 +- .../re.regex.construct/bad_range.pass.cpp | 2 +- .../re.regex.construct/bad_repeat.pass.cpp | 2 +- .../re.regex.construct/deduct.fail.cpp | 5 +- .../re.regex.construct/deduct.pass.cpp | 15 +- .../re.regex.construct/default.pass.cpp | 2 + .../re.regex.construct/il_flg.pass.cpp | 2 +- .../re.regex.nonmemb/nothing_to_do.pass.cpp | 13 - test/std/re/re.req/nothing_to_do.pass.cpp | 1 - ...range_concept_conformance.compile.pass.cpp | 38 + .../re.results.all/get_allocator.pass.cpp | 2 + .../re.results.const/allocator.pass.cpp | 2 + .../re.results/re.results.const/copy.pass.cpp | 4 + .../re.results.const/copy_assign.pass.cpp | 10 +- .../re.results.const/default.pass.cpp | 25 +- .../re.results/re.results.const/move.pass.cpp | 15 +- .../re.results.const/move_assign.pass.cpp | 10 +- .../re.results/re.results.form/form1.pass.cpp | 2 + .../re.results/re.results.form/form2.pass.cpp | 4 +- .../re.results/re.results.form/form3.pass.cpp | 4 +- .../re.results/re.results.form/form4.pass.cpp | 2 + .../re.results/re.results.size/empty.fail.cpp | 28 - .../re.results.size/empty.verify.cpp | 26 + .../compare_string_type.pass.cpp | 2 + .../compare_sub_match.pass.cpp | 2 + .../compare_value_type_ptr.pass.cpp | 2 + .../re.submatch.members/default.pass.cpp | 2 + .../re.submatch.members/length.pass.cpp | 2 + .../operator_string.pass.cpp | 2 + .../re.submatch.members/str.pass.cpp | 2 + .../re.submatch.op/compare.pass.cpp | 4 +- .../re.submatch.op/stream.pass.cpp | 2 + test/std/re/re.submatch/types.pass.cpp | 15 +- test/std/re/re.syn/wcmatch.pass.cpp | 2 + test/std/re/re.syn/wcregex_iterator.pass.cpp | 2 + .../re/re.syn/wcregex_token_iterator.pass.cpp | 2 + test/std/re/re.syn/wcsub_match.pass.cpp | 2 + test/std/re/re.syn/wregex.pass.cpp | 2 + test/std/re/re.syn/wsmatch.pass.cpp | 2 + test/std/re/re.syn/wsregex_iterator.pass.cpp | 2 + .../re/re.syn/wsregex_token_iterator.pass.cpp | 2 + test/std/re/re.syn/wssub_match.pass.cpp | 2 + test/std/re/re.traits/default.pass.cpp | 26 +- test/std/re/re.traits/getloc.pass.cpp | 25 +- test/std/re/re.traits/isctype.pass.cpp | 8 +- test/std/re/re.traits/length.pass.cpp | 3 +- .../re/re.traits/lookup_classname.pass.cpp | 6 +- .../re/re.traits/lookup_collatename.pass.cpp | 5 +- test/std/re/re.traits/transform.pass.cpp | 4 +- .../re/re.traits/transform_primary.pass.cpp | 4 +- test/std/re/re.traits/translate.pass.cpp | 3 +- .../re/re.traits/translate_nocase.pass.cpp | 3 +- test/std/re/re.traits/types.pass.cpp | 3 +- test/std/re/re.traits/value.pass.cpp | 2 + .../basic.string.hash/char_type_hash.fail.cpp | 12 +- .../basic.string.hash/enabled_hashes.pass.cpp | 4 +- .../basic.string.hash/strings.pass.cpp | 4 +- .../basic.string.literals/literal.pass.cpp | 83 +- .../basic.string.literals/literal.verify.cpp | 21 + .../basic.string.literals/literal1.fail.cpp | 22 - .../basic.string.literals/literal1.pass.cpp | 24 - .../basic.string.literals/literal2.fail.cpp | 20 - .../basic.string.literals/literal2.pass.cpp | 24 - .../basic.string.literals/literal3.pass.cpp | 24 - ...pp => allocator_mismatch.compile.fail.cpp} | 0 .../basic.string/cpp17_input_iterator.h | 40 + .../std/strings/basic.string/input_iterator.h | 40 - ...range_concept_conformance.compile.pass.cpp | 38 + .../basic.string/string.access/at.pass.cpp | 5 - .../basic.string/string.access/back.pass.cpp | 13 +- .../string.access/db_back.pass.cpp | 56 - .../string.access/db_cback.pass.cpp | 52 - .../string.access/db_cfront.pass.cpp | 52 - .../string.access/db_cindex.pass.cpp | 54 - .../string.access/db_front.pass.cpp | 56 - .../string.access/db_index.pass.cpp | 54 - .../basic.string/string.access/front.pass.cpp | 13 +- .../basic.string/string.access/index.pass.cpp | 15 +- .../string.capacity/capacity.pass.cpp | 8 +- .../string.capacity/empty.fail.cpp | 29 - .../string.capacity/empty.verify.cpp | 27 + .../string.capacity/max_size.pass.cpp | 2 +- .../string.capacity/over_max_size.pass.cpp | 8 +- .../reserve.deprecated_in_cxx20.verify.cpp | 22 + .../string.capacity/reserve.pass.cpp | 107 +- .../string.capacity/reserve_size.pass.cpp | 104 + .../resize_and_overwrite.pass.cpp | 107 + .../string.capacity/resize_size.pass.cpp | 5 - .../string.capacity/resize_size_char.pass.cpp | 5 - ...hrink_to_fit.explicit_instantiation.sh.cpp | 59 + .../string.cons/brace_assignment.pass.cpp | 2 +- .../string.cons/default_noexcept.pass.cpp | 2 +- .../string.cons/dtor_noexcept.pass.cpp | 4 +- .../implicit_deduction_guides.pass.cpp | 71 +- .../string.cons/initializer_list.pass.cpp | 6 +- .../initializer_list_assignment.pass.cpp | 2 +- .../string.cons/iter_alloc.pass.cpp | 34 +- .../string.cons/iter_alloc_deduction.fail.cpp | 10 +- .../string.cons/iter_alloc_deduction.pass.cpp | 6 +- .../basic.string/string.cons/move.pass.cpp | 2 +- .../string.cons/move_alloc.pass.cpp | 19 +- .../string.cons/move_assign_noexcept.pass.cpp | 2 +- .../string.cons/move_assignment.pass.cpp | 2 +- .../string.cons/move_noexcept.pass.cpp | 2 +- .../string.cons/nullptr.compile.pass.cpp | 21 + ....fail.cpp => string_view.compile.fail.cpp} | 0 .../string_view_deduction.fail.cpp | 4 +- .../string_view_deduction.pass.cpp | 8 +- .../string_view_size_size_deduction.fail.cpp | 4 +- .../string_view_size_size_deduction.pass.cpp | 8 +- .../basic.string/string.cons/substr.pass.cpp | 5 - .../string.contains/contains.char.pass.cpp | 41 + .../string.contains/contains.ptr.pass.cpp | 71 + .../contains.string_view.pass.cpp | 92 + .../string.ends_with/ends_with.char.pass.cpp | 2 +- .../string.ends_with/ends_with.ptr.pass.cpp | 2 +- .../ends_with.string_view.pass.cpp | 2 +- .../string.iterators/db_iterators_2.pass.cpp | 56 - .../string.iterators/db_iterators_3.pass.cpp | 56 - .../string.iterators/db_iterators_4.pass.cpp | 56 - .../string.iterators/db_iterators_5.pass.cpp | 60 - .../string.iterators/db_iterators_6.pass.cpp | 58 - .../string.iterators/db_iterators_7.pass.cpp | 58 - .../string.iterators/db_iterators_8.pass.cpp | 54 - ...rator_concept_conformance.compile.pass.cpp | 62 + .../string.iterators/iterators.pass.cpp | 103 +- .../string.modifiers/nothing_to_do.pass.cpp | 13 - .../robust_against_adl.pass.cpp | 35 + .../string_append/T_size_size.pass.cpp | 5 - .../string_append/initializer_list.pass.cpp | 2 +- .../string_append/iterator.pass.cpp | 109 +- .../string_append/push_back.pass.cpp | 2 +- .../string_append/string_size_size.pass.cpp | 5 - .../string_assign/T_size_size.pass.cpp | 5 - .../string_assign/initializer_list.pass.cpp | 2 +- .../string_assign/iterator.pass.cpp | 101 +- .../string_assign/string_size_size.pass.cpp | 5 - .../string_copy/copy.pass.cpp | 5 - .../string_erase/size_size.pass.cpp | 5 - .../iter_initializer_list.pass.cpp | 2 +- .../string_insert/iter_iter_iter.pass.cpp | 122 +- .../string_insert/size_T_size_size.pass.cpp | 5 - .../string_insert/size_pointer.pass.cpp | 5 - .../string_insert/size_pointer_size.pass.cpp | 5 - .../string_insert/size_size_char.pass.cpp | 5 - .../string_insert/size_string.pass.cpp | 5 - .../size_string_size_size.pass.cpp | 5 - .../string_insert/string_view.pass.cpp | 5 - .../initializer_list.pass.cpp | 2 +- .../iter_iter_initializer_list.pass.cpp | 2 +- .../iter_iter_iter_iter.pass.cpp | 29 +- .../size_size_T_size_size.pass.cpp | 5 - .../string_replace/size_size_pointer.pass.cpp | 5 - .../size_size_pointer_size.pass.cpp | 5 - .../size_size_size_char.pass.cpp | 5 - .../string_replace/size_size_string.pass.cpp | 5 - .../size_size_string_size_size.pass.cpp | 5 - .../size_size_string_view.pass.cpp | 5 - .../string.nonmembers/nothing_to_do.pass.cpp | 13 - .../string.io/get_line.pass.cpp | 10 +- .../string.io/get_line_delim.pass.cpp | 10 +- .../string.io/get_line_delim_rv.pass.cpp | 10 +- .../string.io/get_line_rv.pass.cpp | 10 +- .../string.nonmembers/string.io/lit.local.cfg | 3 + .../string.io/stream_extract.pass.cpp | 6 +- .../string.io/stream_insert.pass.cpp | 6 +- .../string.special/swap_noexcept.pass.cpp | 2 +- .../string.ops/nothing_to_do.pass.cpp | 13 - .../string_compare/pointer.pass.cpp | 1 + .../string_compare/size_size_pointer.pass.cpp | 5 - .../size_size_pointer_size.pass.cpp | 5 - .../string_compare/size_size_string.pass.cpp | 5 - .../size_size_string_size_size.pass.cpp | 5 - .../size_size_string_view.pass.cpp | 7 +- .../string.ops/string_compare/string.pass.cpp | 1 + .../string_compare/string_view.pass.cpp | 1 + .../char_size.pass.cpp | 2 + .../pointer_size.pass.cpp | 1 + .../pointer_size_size.pass.cpp | 1 + .../string_size.pass.cpp | 2 + .../string_view_size.pass.cpp | 2 + .../string_find.first.of/char_size.pass.cpp | 2 + .../pointer_size.pass.cpp | 2 + .../pointer_size_size.pass.cpp | 1 + .../string_find.first.of/string_size.pass.cpp | 2 + .../string_view_size.pass.cpp | 2 + .../char_size.pass.cpp | 2 + .../pointer_size.pass.cpp | 2 + .../pointer_size_size.pass.cpp | 1 + .../string_size.pass.cpp | 2 + .../string_view_size.pass.cpp | 2 + .../string_find.last.of/char_size.pass.cpp | 2 + .../string_find.last.of/pointer_size.pass.cpp | 2 + .../pointer_size_size.pass.cpp | 1 + .../string_find.last.of/string_size.pass.cpp | 2 + .../string_view_size.pass.cpp | 2 + .../string.ops/string_find/char_size.pass.cpp | 2 + .../string_find/pointer_size.pass.cpp | 2 + .../string_find/pointer_size_size.pass.cpp | 1 + .../string_find/string_size.pass.cpp | 2 + .../string_find/string_view_size.pass.cpp | 2 + .../string_rfind/char_size.pass.cpp | 2 + .../string_rfind/pointer_size.pass.cpp | 2 + .../string_rfind/pointer_size_size.pass.cpp | 1 + .../string_rfind/string_size.pass.cpp | 2 + .../string_rfind/string_view_size.pass.cpp | 2 + .../string.ops/string_substr/substr.pass.cpp | 5 - .../starts_with.char.pass.cpp | 2 +- .../starts_with.ptr.pass.cpp | 2 +- .../starts_with.string_view.pass.cpp | 2 +- test/std/strings/basic.string/test_traits.h | 2 +- ...l.cpp => traits_mismatch.compile.fail.cpp} | 0 test/std/strings/c.strings/cstring.pass.cpp | 20 +- test/std/strings/c.strings/cuchar.pass.cpp | 7 +- test/std/strings/c.strings/cwchar.pass.cpp | 54 +- test/std/strings/c.strings/cwctype.pass.cpp | 4 +- .../assign3.pass.cpp | 13 +- .../copy.pass.cpp | 13 +- .../lt.pass.cpp | 18 +- .../move.pass.cpp | 13 +- .../assign2.pass.cpp | 2 +- .../assign3.pass.cpp | 15 +- .../compare.pass.cpp | 2 +- .../copy.pass.cpp | 15 +- .../eq.pass.cpp | 2 +- .../eq_int_type.pass.cpp | 2 +- .../find.pass.cpp | 2 +- .../length.pass.cpp | 2 +- .../lt.pass.cpp | 2 +- .../move.pass.cpp | 15 +- .../not_eof.pass.cpp | 2 +- .../to_char_type.pass.cpp | 2 +- .../to_int_type.pass.cpp | 2 +- .../types.pass.cpp | 2 +- .../assign2.pass.cpp | 2 +- .../assign3.pass.cpp | 15 +- .../compare.pass.cpp | 2 +- .../copy.pass.cpp | 15 +- .../eq.pass.cpp | 2 +- .../eq_int_type.pass.cpp | 2 +- .../find.pass.cpp | 2 +- .../length.pass.cpp | 2 +- .../lt.pass.cpp | 2 +- .../move.pass.cpp | 15 +- .../not_eof.pass.cpp | 2 +- .../to_char_type.pass.cpp | 2 +- .../to_int_type.pass.cpp | 2 +- .../types.pass.cpp | 2 +- .../assign2.pass.cpp | 2 +- .../assign3.pass.cpp | 16 +- .../compare.pass.cpp | 2 +- .../copy.pass.cpp | 16 +- .../eof.pass.cpp | 2 +- .../eq.pass.cpp | 2 +- .../eq_int_type.pass.cpp | 2 +- .../find.pass.cpp | 2 +- .../length.pass.cpp | 4 +- .../lt.pass.cpp | 2 +- .../move.pass.cpp | 16 +- .../not_eof.pass.cpp | 2 +- .../to_char_type.pass.cpp | 2 +- .../to_int_type.pass.cpp | 2 +- .../types.pass.cpp | 8 +- .../assign2.pass.cpp | 2 + .../assign3.pass.cpp | 15 +- .../compare.pass.cpp | 2 + .../copy.pass.cpp | 15 +- .../eof.pass.cpp | 2 + .../eq.pass.cpp | 2 + .../eq_int_type.pass.cpp | 2 + .../find.pass.cpp | 2 + .../length.pass.cpp | 2 + .../lt.pass.cpp | 16 +- .../move.pass.cpp | 15 +- .../not_eof.pass.cpp | 2 + .../to_char_type.pass.cpp | 2 + .../to_int_type.pass.cpp | 2 + .../types.pass.cpp | 2 + .../nothing_to_do.pass.cpp | 13 - .../char.traits/nothing_to_do.pass.cpp | 13 - .../strings/string.classes/typedefs.pass.cpp | 4 +- .../strings/string.conversions/stod.pass.cpp | 296 +- .../strings/string.conversions/stof.pass.cpp | 237 +- .../strings/string.conversions/stoi.pass.cpp | 154 +- .../strings/string.conversions/stol.pass.cpp | 147 +- .../strings/string.conversions/stold.pass.cpp | 236 +- .../strings/string.conversions/stoll.pass.cpp | 146 +- .../strings/string.conversions/stoul.pass.cpp | 145 +- .../string.conversions/stoull.pass.cpp | 146 +- .../string.conversions/to_string.pass.cpp | 16 +- .../string.conversions/to_wstring.pass.cpp | 18 +- .../enable_borrowed_range.compile.pass.cpp | 27 + ...range_concept_conformance.compile.pass.cpp | 38 + .../string.view.access/at.pass.cpp | 5 - .../string.view.access/back.pass.cpp | 1 - .../string.view.access/data.pass.cpp | 1 - .../string.view.access/front.pass.cpp | 1 - .../string.view.access/index.pass.cpp | 1 - .../string.view.capacity/capacity.pass.cpp | 16 +- .../string.view.capacity/empty.fail.cpp | 29 - .../string.view.capacity/empty.verify.cpp | 27 + .../string.view.comparison/equal.pass.cpp | 116 + .../string.view.comparison/greater.pass.cpp | 116 + .../greater_equal.pass.cpp | 116 + .../string.view.comparison/less.pass.cpp | 116 + .../less_equal.pass.cpp | 116 + .../string.view.comparison/not_equal.pass.cpp | 116 + .../opeq.string_view.pointer.pass.cpp | 70 - .../opeq.string_view.string.pass.cpp | 54 - .../opeq.string_view.string_view.pass.cpp | 63 - .../opge.string_view.pointer.pass.cpp | 73 - .../opge.string_view.string.pass.cpp | 53 - .../opge.string_view.string_view.pass.cpp | 66 - .../opgt.string_view.pointer.pass.cpp | 73 - .../opgt.string_view.string.pass.cpp | 53 - .../opgt.string_view.string_view.pass.cpp | 66 - .../ople.string_view.pointer.pass.cpp | 73 - .../ople.string_view.string.pass.cpp | 53 - .../ople.string_view.string_view.pass.cpp | 66 - .../oplt.string_view.pointer.pass.cpp | 73 - .../oplt.string_view.string.pass.cpp | 53 - .../oplt.string_view.string_view.pass.cpp | 66 - .../opne.string_view.pointer.pass.cpp | 71 - .../opne.string_view.string.pass.cpp | 53 - .../opne.string_view.string_view.pass.cpp | 63 - .../string.view.cons/assign.pass.cpp | 17 +- .../string.view.cons/default.pass.cpp | 4 +- .../from_iterator_sentinel.pass.cpp | 92 + .../string.view.cons/from_literal.pass.cpp | 1 - .../string.view.cons/from_ptr_len.pass.cpp | 1 - .../string.view.cons/from_range.pass.cpp | 199 + .../string.view.cons/from_string.pass.cpp | 3 +- .../from_string1.compile.fail.cpp | 32 + .../string.view.cons/from_string1.fail.cpp | 33 - .../from_string2.compile.fail.cpp | 32 + .../string.view.cons/from_string2.fail.cpp | 33 - .../implicit_deduction_guides.pass.cpp | 11 +- .../string.view.cons/nullptr.compile.pass.cpp | 20 + .../iterator_sentinel.pass.cpp | 49 + .../string.view.deduct/range.pass.cpp | 57 + .../string.view.find/find_char_size.pass.cpp | 1 + .../find_first_not_of_char_size.pass.cpp | 2 + .../find_first_not_of_pointer_size.pass.cpp | 1 + ...nd_first_not_of_pointer_size_size.pass.cpp | 1 + ...ind_first_not_of_string_view_size.pass.cpp | 1 + .../find_first_of_char_size.pass.cpp | 3 +- .../find_first_of_pointer_size.pass.cpp | 4 +- .../find_first_of_pointer_size_size.pass.cpp | 3 +- .../find_first_of_string_view_size.pass.cpp | 4 +- .../find_last_not_of_char_size.pass.cpp | 4 +- .../find_last_not_of_pointer_size.pass.cpp | 1 + ...ind_last_not_of_pointer_size_size.pass.cpp | 3 +- ...find_last_not_of_string_view_size.pass.cpp | 2 + .../find_last_of_char_size.pass.cpp | 2 + .../find_last_of_pointer_size.pass.cpp | 2 + .../find_last_of_pointer_size_size.pass.cpp | 1 + .../find_last_of_string_view_size.pass.cpp | 2 + .../find_pointer_size.pass.cpp | 4 +- .../find_pointer_size_size.pass.cpp | 1 + .../find_string_view_size.pass.cpp | 2 + .../string.view.find/rfind_char_size.pass.cpp | 2 + .../rfind_pointer_size.pass.cpp | 2 + .../rfind_pointer_size_size.pass.cpp | 1 + .../rfind_string_view_size.pass.cpp | 2 + .../string.view.hash/char_type.hash.fail.cpp | 13 +- .../string.view.hash/enabled_hashes.pass.cpp | 4 +- .../string.view.hash/string_view.pass.cpp | 4 +- .../string.view.io/stream_insert.pass.cpp | 17 +- ...tream_insert_decl_present.compile.pass.cpp | 24 + .../stream_insert_decl_present.pass.cpp | 26 - .../string.view.iterators/begin.pass.cpp | 22 +- .../string.view.iterators/end.pass.cpp | 22 +- ...rator_concept_conformance.compile.pass.cpp | 47 + .../string.view.iterators/rbegin.pass.cpp | 22 +- .../string.view.iterators/rend.pass.cpp | 22 +- .../remove_prefix.pass.cpp | 3 +- .../remove_suffix.pass.cpp | 3 +- .../string.view.modifiers/swap.pass.cpp | 3 +- .../string.view.nonmem/quoted.pass.cpp | 45 +- .../string.view.ops/compare.sv.pass.cpp | 2 +- .../string.view/string.view.ops/copy.pass.cpp | 26 + .../string.view.synop/nothing_to_do.pass.cpp | 2 - .../contains.char.pass.cpp | 45 + .../contains.ptr.pass.cpp | 75 + .../contains.string_view.pass.cpp | 89 + .../ends_with.char.pass.cpp | 3 +- .../ends_with.ptr.pass.cpp | 5 +- .../ends_with.string_view.pass.cpp | 3 +- .../nothing_to_do.pass.cpp | 15 - .../starts_with.char.pass.cpp | 3 +- .../starts_with.ptr.pass.cpp | 3 +- .../starts_with.string_view.pass.cpp | 3 +- .../string_view.literals/literal.pass.cpp | 110 +- .../string_view.literals/literal.verify.cpp | 21 + .../string_view.literals/literal1.fail.cpp | 24 - .../string_view.literals/literal1.pass.cpp | 28 - .../string_view.literals/literal2.fail.cpp | 22 - .../string_view.literals/literal2.pass.cpp | 28 - .../string_view.literals/literal3.pass.cpp | 28 - ...l.cpp => traits_mismatch.compile.fail.cpp} | 0 .../trivially_copyable.compile.pass.cpp | 26 + .../strings/strings.erasure/erase.pass.cpp | 71 +- .../strings/strings.erasure/erase_if.pass.cpp | 64 +- .../strings.general/nothing_to_do.pass.cpp | 1 - .../futures/futures.async/async.fail.cpp | 39 - .../futures/futures.async/async.pass.cpp | 4 +- .../futures/futures.async/async.verify.cpp | 38 + .../futures.async/async_race.38682.pass.cpp | 13 +- .../futures/futures.async/async_race.pass.cpp | 4 +- .../futures.future_error/what.pass.cpp | 6 +- .../futures.overview/future_errc.pass.cpp | 2 +- .../futures.promise/alloc_ctor.pass.cpp | 29 +- .../futures.promise/copy_assign.fail.cpp | 52 - .../futures.promise/copy_assign.verify.cpp | 37 + .../futures.promise/copy_ctor.fail.cpp | 52 - .../futures.promise/copy_ctor.verify.cpp | 37 + .../futures/futures.promise/default.pass.cpp | 2 +- .../futures/futures.promise/dtor.pass.cpp | 2 +- .../futures.promise/get_future.pass.cpp | 2 +- .../futures.promise/move_assign.pass.cpp | 47 +- .../futures.promise/move_ctor.pass.cpp | 35 +- .../futures.promise/set_exception.pass.cpp | 4 +- .../set_exception_at_thread_exit.pass.cpp | 7 +- .../futures.promise/set_lvalue.pass.cpp | 2 +- .../set_lvalue_at_thread_exit.pass.cpp | 5 +- .../futures.promise/set_rvalue.pass.cpp | 4 +- .../set_rvalue_at_thread_exit.pass.cpp | 5 +- .../set_value_at_thread_exit_const.pass.cpp | 5 +- .../set_value_at_thread_exit_void.pass.cpp | 5 +- .../futures.promise/set_value_const.pass.cpp | 2 +- .../futures.promise/set_value_void.pass.cpp | 4 +- .../futures/futures.promise/swap.pass.cpp | 57 +- .../copy_assign.pass.cpp | 2 +- .../futures.shared_future/copy_ctor.pass.cpp | 2 +- .../ctor_future.pass.cpp | 2 +- .../futures.shared_future/dtor.pass.cpp | 37 +- .../futures.shared_future/get.pass.cpp | 15 +- .../move_assign.pass.cpp | 2 +- .../futures.shared_future/move_ctor.pass.cpp | 2 +- .../futures.shared_future/wait.pass.cpp | 9 +- .../futures.shared_future/wait_for.pass.cpp | 159 +- .../futures.shared_future/wait_until.pass.cpp | 138 +- .../futures.state/nothing_to_do.pass.cpp | 1 - .../futures.task.members/assign_copy.fail.cpp | 2 +- .../futures.task.members/assign_move.pass.cpp | 4 +- .../futures.task.members/ctor1.fail.cpp | 2 +- .../futures.task.members/ctor2.fail.cpp | 2 +- .../futures.task.members/ctor_copy.fail.cpp | 2 +- .../ctor_default.pass.cpp | 2 +- .../futures.task.members/ctor_func.pass.cpp | 6 +- .../ctor_func_alloc.pass.cpp | 29 +- .../futures.task.members/ctor_move.pass.cpp | 4 +- .../futures.task.members/dtor.pass.cpp | 12 +- .../futures.task.members/get_future.pass.cpp | 4 +- .../make_ready_at_thread_exit.pass.cpp | 32 +- .../futures.task.members/operator.pass.cpp | 32 +- .../futures.task.members/reset.pass.cpp | 6 +- .../futures.task.members/swap.pass.cpp | 4 +- .../futures.task.nonmembers/swap.pass.cpp | 4 +- .../uses_allocator.compile.pass.cpp | 26 + .../uses_allocator.pass.cpp | 36 - .../copy_assign.fail.cpp | 52 - .../copy_assign.verify.cpp | 37 + .../futures.unique_future/copy_ctor.fail.cpp | 52 - .../copy_ctor.verify.cpp | 37 + .../futures.unique_future/dtor.pass.cpp | 37 +- .../futures.unique_future/get.pass.cpp | 15 +- .../move_assign.pass.cpp | 2 +- .../futures.unique_future/move_ctor.pass.cpp | 2 +- .../futures.unique_future/share.pass.cpp | 2 +- .../futures.unique_future/wait.pass.cpp | 69 +- .../futures.unique_future/wait_for.pass.cpp | 104 +- .../futures.unique_future/wait_until.pass.cpp | 135 +- .../std/thread/thread.barrier/arrive.pass.cpp | 37 + .../thread.barrier/arrive_and_drop.pass.cpp | 36 + .../thread.barrier/arrive_and_wait.pass.cpp | 36 + .../thread/thread.barrier/completion.pass.cpp | 41 + test/std/thread/thread.barrier/max.pass.cpp | 26 + .../notify_all_at_thread_exit.pass.cpp | 5 +- ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../thread.condition.condvar/default.pass.cpp | 1 + .../destructor.pass.cpp | 5 +- .../notify_all.pass.cpp | 5 +- .../notify_one.pass.cpp | 136 +- .../thread.condition.condvar/wait.pass.cpp | 5 +- .../wait_for.pass.cpp | 27 +- .../wait_for_pred.pass.cpp | 6 +- .../wait_pred.pass.cpp | 4 +- .../wait_until.pass.cpp | 6 +- .../wait_until_pred.pass.cpp | 12 +- ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../destructor.pass.cpp | 5 +- .../notify_all.pass.cpp | 65 +- .../notify_one.pass.cpp | 8 +- .../thread.condition.condvarany/wait.pass.cpp | 3 +- .../wait_for.pass.cpp | 23 +- .../wait_for_pred.pass.cpp | 6 +- .../wait_pred.pass.cpp | 4 +- .../wait_terminates.sh.cpp | 20 +- .../wait_until.pass.cpp | 6 +- .../wait_until_pred.pass.cpp | 8 +- .../thread.latch/arrive_and_wait.pass.cpp | 34 + .../thread/thread.latch/count_down.pass.cpp | 35 + test/std/thread/thread.latch/max.pass.cpp | 23 + .../std/thread/thread.latch/try_wait.pass.cpp | 31 + .../thread.lock.algorithm/lock.pass.cpp | 16 +- .../thread.lock.algorithm/try_lock.pass.cpp | 4 +- .../thread.lock.guard/adopt_lock.pass.cpp | 36 +- ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../thread.lock.guard/mutex.pass.cpp | 42 +- .../thread.lock.scoped/adopt_lock.pass.cpp | 2 +- .../thread.lock.scoped/assign.fail.cpp | 2 +- .../thread.lock.scoped/copy.fail.cpp | 2 +- .../thread.lock.scoped/mutex.fail.cpp | 2 +- .../thread.lock.scoped/mutex.pass.cpp | 4 +- .../thread.lock.scoped/types.pass.cpp | 6 +- .../copy_assign.compile.fail.cpp | 28 + .../copy_assign.fail.cpp | 28 - .../copy_ctor.compile.fail.cpp | 26 + .../copy_ctor.fail.cpp | 26 - .../thread.lock.shared.cons/default.pass.cpp | 6 +- .../move_assign.pass.cpp | 6 +- .../move_ctor.pass.cpp | 6 +- .../thread.lock.shared.cons/mutex.pass.cpp | 16 +- .../mutex_adopt_lock.pass.cpp | 7 +- .../mutex_defer_lock.pass.cpp | 7 +- .../mutex_duration.pass.cpp | 102 +- .../mutex_time_point.pass.cpp | 95 +- .../mutex_try_to_lock.pass.cpp | 10 +- .../thread.lock.shared.locking/lock.pass.cpp | 10 +- .../try_lock.pass.cpp | 5 +- .../try_lock_for.pass.cpp | 4 +- .../try_lock_until.pass.cpp | 4 +- .../unlock.pass.cpp | 3 +- .../member_swap.pass.cpp | 2 +- .../nonmember_swap.pass.cpp | 2 +- .../thread.lock.shared.mod/release.pass.cpp | 2 +- .../thread.lock.shared.obs/mutex.pass.cpp | 6 +- .../thread.lock.shared.obs/op_bool.pass.cpp | 21 +- .../thread.lock.shared.obs/owns_lock.pass.cpp | 6 +- .../thread.lock.shared/types.pass.cpp | 3 +- ....fail.cpp => copy_assign.compile.fail.cpp} | 0 ...or.fail.cpp => copy_ctor.compile.fail.cpp} | 0 .../move_assign.pass.cpp | 2 +- .../move_ctor.pass.cpp | 2 +- .../thread.lock.unique.cons/mutex.pass.cpp | 8 +- .../mutex_duration.pass.cpp | 8 +- .../mutex_time_point.pass.cpp | 8 +- .../mutex_try_to_lock.pass.cpp | 6 +- .../thread.lock.unique.locking/lock.pass.cpp | 6 +- .../try_lock.pass.cpp | 2 + .../thread.lock.unique.obs/op_bool.pass.cpp | 7 +- .../thread.mutex/thread.lock/types.fail.cpp | 6 +- .../nothing_to_do.pass.cpp | 13 - .../nothing_to_do.pass.cpp | 13 - ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../thread.mutex.class/lock.pass.cpp | 6 +- .../thread.mutex.class/try_lock.pass.cpp | 4 +- ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../thread.mutex.recursive/lock.pass.cpp | 6 +- .../thread.mutex.recursive/try_lock.pass.cpp | 4 +- .../lit.local.cfg | 2 - .../nothing_to_do.pass.cpp | 13 - .../thread.shared_mutex.class/assign.fail.cpp | 5 +- .../thread.shared_mutex.class/copy.fail.cpp | 5 +- .../default.pass.cpp | 5 +- .../thread.shared_mutex.class/lock.pass.cpp | 10 +- .../lock_shared.pass.cpp | 14 +- .../try_lock.pass.cpp | 10 +- .../try_lock_shared.pass.cpp | 10 +- .../lit.local.cfg | 2 - .../nothing_to_do.pass.cpp | 13 - .../assign.compile.fail.cpp | 29 + .../assign.fail.cpp | 25 - .../copy.compile.fail.cpp | 28 + .../copy.fail.cpp | 24 - .../default.pass.cpp | 5 +- .../lock.pass.cpp | 50 +- .../lock_shared.pass.cpp | 113 +- .../try_lock.pass.cpp | 10 +- .../try_lock_for.pass.cpp | 11 +- .../try_lock_shared.pass.cpp | 10 +- .../try_lock_shared_for.pass.cpp | 12 +- .../try_lock_shared_until.pass.cpp | 95 +- .../try_lock_until.pass.cpp | 12 +- .../try_lock_until_deadlock_bug.pass.cpp | 12 +- .../nothing_to_do.pass.cpp | 13 - ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../thread.timedmutex.class/default.pass.cpp | 2 +- .../thread.timedmutex.class/lock.pass.cpp | 6 +- .../thread.timedmutex.class/try_lock.pass.cpp | 6 +- .../try_lock_for.pass.cpp | 8 +- .../try_lock_until.pass.cpp | 8 +- ...ssign.fail.cpp => assign.compile.fail.cpp} | 0 .../{copy.fail.cpp => copy.compile.fail.cpp} | 0 .../default.pass.cpp | 2 +- .../thread.timedmutex.recursive/lock.pass.cpp | 8 +- .../try_lock.pass.cpp | 6 +- .../try_lock_for.pass.cpp | 8 +- .../try_lock_until.pass.cpp | 8 +- .../thread.once/nothing_to_do.pass.cpp | 13 - .../thread.once.callonce/call_once.pass.cpp | 27 +- .../thread.once.callonce/race.pass.cpp | 7 +- .../assign.compile.fail.cpp | 26 + .../thread.once.onceflag/assign.fail.cpp | 24 - .../copy.compile.fail.cpp | 25 + .../thread.once.onceflag/copy.fail.cpp | 23 - .../thread.once.onceflag/default.pass.cpp | 2 + .../thread/thread.req/nothing_to_do.pass.cpp | 13 - .../nothing_to_do.pass.cpp | 13 - .../thread/thread.semaphore/acquire.pass.cpp | 35 + .../thread/thread.semaphore/binary.pass.cpp | 45 + .../thread.semaphore/ctor.compile.pass.cpp | 31 + test/std/thread/thread.semaphore/max.pass.cpp | 26 + .../thread/thread.semaphore/release.pass.cpp | 38 + .../thread/thread.semaphore/timed.pass.cpp | 49 + .../thread.semaphore/try_acquire.pass.cpp | 42 + .../thread.thread.algorithm/swap.pass.cpp | 3 +- .../copy.compile.fail.cpp | 23 + .../thread.thread.assign/copy.fail.cpp | 52 - .../thread.thread.assign/move.pass.cpp | 27 +- .../thread.thread.assign/move2.pass.cpp | 36 +- .../thread.thread.constr/F.pass.cpp | 22 +- .../constr.compile.fail.cpp | 25 + .../thread.thread.constr/constr.fail.cpp | 27 - .../copy.compile.fail.cpp | 22 + .../thread.thread.constr/copy.fail.cpp | 67 - .../thread.thread.constr/move.pass.cpp | 26 +- .../robust_against_adl.pass.cpp | 33 + .../thread.thread.destr/dtor.pass.cpp | 3 +- .../thread.thread.id/enabled_hashes.pass.cpp | 2 +- .../thread.thread.id/stream.pass.cpp | 3 +- .../thread.thread.member/detach.pass.cpp | 13 +- .../thread.thread.member/get_id.pass.cpp | 3 +- .../thread.thread.member/join.pass.cpp | 15 +- .../thread.thread.member/joinable.pass.cpp | 3 +- .../thread.thread.member/swap.pass.cpp | 3 +- .../sleep_for_tested_elsewhere.pass.cpp | 1 - .../thread.thread.this/sleep_until.pass.cpp | 20 +- .../allocator.adaptor.cnstr/allocs.pass.cpp | 4 +- .../converting_copy.pass.cpp | 2 +- .../converting_move.pass.cpp | 2 +- .../allocator.adaptor.cnstr/copy.pass.cpp | 2 +- .../allocator.adaptor.cnstr/deduct.pass.cpp | 64 + .../allocator.adaptor.cnstr/default.pass.cpp | 2 +- .../allocate_size.fail.cpp | 30 - .../allocate_size.pass.cpp | 2 +- .../allocate_size.verify.cpp | 29 + .../allocate_size_hint.fail.cpp | 30 - .../allocate_size_hint.pass.cpp | 2 +- .../allocate_size_hint.verify.cpp | 29 + .../construct.pass.cpp | 25 +- .../construct_pair.pass.cpp | 2 +- .../construct_pair_const_lvalue_pair.pass.cpp | 2 +- .../construct_pair_piecewise.pass.cpp | 2 +- .../construct_pair_rvalue.pass.cpp | 2 +- .../construct_pair_values.pass.cpp | 2 +- .../construct_type.pass.cpp | 2 +- .../deallocate.pass.cpp | 2 +- .../destroy.pass.cpp | 2 +- .../inner_allocator.pass.cpp | 2 +- .../max_size.pass.cpp | 2 +- .../outer_allocator.pass.cpp | 2 +- ...ct_on_container_copy_construction.pass.cpp | 2 +- .../allocator_pointers.pass.cpp | 2 +- .../inner_allocator_type.pass.cpp | 2 +- .../is_always_equal.pass.cpp | 2 +- ...gate_on_container_copy_assignment.pass.cpp | 2 +- ...gate_on_container_move_assignment.pass.cpp | 2 +- .../propagate_on_container_swap.pass.cpp | 2 +- .../copy_assign.pass.cpp | 2 +- .../scoped.adaptor.operators/eq.pass.cpp | 2 +- .../move_assign.pass.cpp | 2 +- .../allocator.adaptor/types.pass.cpp | 2 +- .../any/any.class/any.assign/copy.pass.cpp | 6 +- .../any/any.class/any.assign/move.pass.cpp | 5 +- .../any/any.class/any.assign/value.pass.cpp | 5 +- .../any/any.class/any.cons/copy.pass.cpp | 5 +- .../any/any.class/any.cons/default.pass.cpp | 2 +- .../any.class/any.cons/in_place_type.pass.cpp | 5 +- .../any/any.class/any.cons/move.pass.cpp | 5 +- .../any/any.class/any.cons/value.pass.cpp | 5 +- .../any.class/any.modifiers/emplace.pass.cpp | 5 +- .../any.class/any.modifiers/reset.pass.cpp | 5 +- .../any/any.class/any.modifiers/swap.pass.cpp | 5 +- .../any.observers/has_value.pass.cpp | 2 +- .../any/any.class/any.observers/type.pass.cpp | 4 +- .../any/any.class/not_literal_type.pass.cpp | 24 - .../any.cast/any_cast_pointer.pass.cpp | 9 +- .../any.cast/any_cast_reference.pass.cpp | 5 +- ...st_request_invalid_value_category.fail.cpp | 6 +- .../any.cast/const_correctness.fail.cpp | 48 - .../any.cast/const_correctness.verify.cpp | 53 + .../any.cast/not_copy_constructible.fail.cpp | 60 - .../not_copy_constructible.verify.cpp | 66 + .../any.cast/reference_types.fail.cpp | 2 +- .../any/any.nonmembers/make_any.pass.cpp | 5 +- .../any/any.nonmembers/swap.pass.cpp | 5 +- .../integral.bool.fail.cpp | 6 +- .../charconv.from.chars/integral.pass.cpp | 82 +- .../integral.roundtrip.pass.cpp | 89 + ..._fixed_precision_to_chars_test_cases_1.hpp | 300 + ..._fixed_precision_to_chars_test_cases_2.hpp | 3477 +++++ ..._fixed_precision_to_chars_test_cases_3.hpp | 10832 ++++++++++++++++ ..._fixed_precision_to_chars_test_cases_4.hpp | 10811 +++++++++++++++ .../double_from_chars_test_cases.hpp | 1146 ++ ..._general_precision_to_chars_test_cases.hpp | 5063 ++++++++ ...uble_hex_precision_to_chars_test_cases.hpp | 120 + ...ntific_precision_to_chars_test_cases_1.hpp | 327 + ...ntific_precision_to_chars_test_cases_2.hpp | 3219 +++++ ...ntific_precision_to_chars_test_cases_3.hpp | 10125 +++++++++++++++ ...ntific_precision_to_chars_test_cases_4.hpp | 10107 ++++++++++++++ .../double_to_chars_test_cases.hpp | 2916 +++++ ...at_fixed_precision_to_chars_test_cases.hpp | 1264 ++ .../float_from_chars_test_cases.hpp | 139 + ..._general_precision_to_chars_test_cases.hpp | 1218 ++ ...loat_hex_precision_to_chars_test_cases.hpp | 106 + ...ientific_precision_to_chars_test_cases.hpp | 1093 ++ .../float_to_chars_test_cases.hpp | 541 + .../floating_point_test_cases.hpp | 278 + .../utilities/charconv/charconv.msvc/test.cpp | 1104 ++ .../utilities/charconv/charconv.msvc/test.hpp | 63 + .../charconv/charconv.msvc/test.pass.cpp | 50 + .../charconv.syn/chars_format.pass.cpp | 78 + .../charconv.syn/from_chars_result.pass.cpp | 57 + .../charconv.syn/to_chars_result.pass.cpp | 57 + .../charconv.to.chars/integral.bool.fail.cpp | 6 +- .../charconv.to.chars/integral.pass.cpp | 18 +- .../format.arg.store/class.pass.cpp | 86 + .../make_format_args.pass.cpp | 42 + .../format.arg.store/make_format_args.sh.cpp | 30 + .../make_wformat_args.pass.cpp | 42 + .../format.arguments/format.arg/ctor.pass.cpp | 50 + .../format.arg/operator_bool.pass.cpp | 64 + .../format.args/ctor.pass.cpp | 71 + .../format.args/types.compile.pass.cpp | 32 + .../format/format.error/format.error.pass.cpp | 51 + .../format.context/advance_to.pass.cpp | 76 + .../format.context/arg.pass.cpp | 63 + .../format.context/ctor.pass.cpp | 145 + .../format.context/locale.pass.cpp | 100 + .../format.context/out.pass.cpp | 72 + .../format.context/types.compile.pass.cpp | 132 + .../format.parse.ctx/advance_to.pass.cpp | 71 + .../format.parse.ctx/begin.pass.cpp | 57 + .../format.parse.ctx/check_arg_id.pass.cpp | 66 + .../format.parse.ctx/check_arg_id.verify.cpp | 33 + .../format.parse.ctx/ctor.pass.cpp | 80 + .../format.parse.ctx/end.pass.cpp | 57 + .../format.parse.ctx/next_arg_id.pass.cpp | 56 + .../format.parse.ctx/types.compile.pass.cpp | 70 + .../format.functions/format.locale.pass.cpp | 75 + .../format/format.functions/format.pass.cpp | 83 + .../format/format.functions/format_tests.h | 2627 ++++ .../format_to.locale.pass.cpp | 89 + .../format.functions/format_to.pass.cpp | 90 + .../format_to_n.locale.pass.cpp | 123 + .../format.functions/format_to_n.pass.cpp | 120 + .../formatted_size.locale.pass.cpp | 64 + .../format.functions/formatted_size.pass.cpp | 61 + .../locale-specific_form.pass.cpp | 2331 ++++ .../format.functions/vformat.locale.pass.cpp | 59 + .../format/format.functions/vformat.pass.cpp | 58 + .../vformat_to.locale.pass.cpp | 88 + .../format.functions/vformat_to.pass.cpp | 89 + .../format.syn/format_to_n_result.pass.cpp | 53 + .../arithmetic.operations/divides.pass.cpp | 4 + .../arithmetic.operations/minus.pass.cpp | 4 + .../arithmetic.operations/modulus.pass.cpp | 4 + .../arithmetic.operations/multiplies.pass.cpp | 4 + .../arithmetic.operations/negate.pass.cpp | 4 + .../arithmetic.operations/plus.pass.cpp | 10 +- .../transparent.pass.cpp | 2 +- .../PR23141_invoke_not_constexpr.pass.cpp | 4 +- .../func.bind.bind/bind_return_type.pass.cpp | 2 +- .../func.bind/func.bind.bind/copy.pass.cpp | 17 +- .../invoke_function_object.pass.cpp | 4 +- .../func.bind.bind/invoke_int_0.pass.cpp | 2 +- .../func.bind.bind/invoke_lvalue.pass.cpp | 2 +- .../func.bind.bind/invoke_rvalue.pass.cpp | 2 +- .../func.bind.bind/invoke_void_0.pass.cpp | 2 +- .../func.bind/func.bind.bind/nested.pass.cpp | 4 +- .../is_bind_expression.pass.cpp | 9 +- .../func.bind.isbind/is_placeholder.pass.cpp | 46 - .../func.bind.isbind/specialization.pass.cpp | 56 + .../func.bind.isplace/is_placeholder.pass.cpp | 53 + .../func.bind.isplace/specialization.pass.cpp | 54 + .../bind/func.bind/nothing_to_do.pass.cpp | 13 - .../bind/nothing_to_do.pass.cpp | 13 - .../bitwise.operations/bit_and.pass.cpp | 4 + .../bitwise.operations/bit_not.pass.cpp | 6 +- .../bitwise.operations/bit_or.pass.cpp | 4 + .../bitwise.operations/bit_xor.pass.cpp | 4 + .../bitwise.operations/transparent.pass.cpp | 2 +- .../comparisons/compare_three_way.pass.cpp | 83 + .../compare_three_way_functional.pass.cpp | 27 + .../comparisons/constexpr_init.pass.cpp | 4 +- .../comparisons/equal_to.pass.cpp | 4 + .../comparisons/greater.pass.cpp | 6 +- .../comparisons/greater_equal.pass.cpp | 6 +- .../comparisons/less.pass.cpp | 6 +- .../comparisons/less_equal.pass.cpp | 6 +- .../comparisons/not_equal_to.pass.cpp | 4 + .../pointer_comparison_test_helper.h | 39 - .../comparisons/transparent.pass.cpp | 2 +- .../transparent_three_way.compile.pass.cpp | 19 + .../func.bind_front/bind_front.pass.cpp | 413 + .../func.bind_front/bind_front.verify.cpp | 50 + .../func.identity/identity.pass.cpp | 77 + .../func.invoke/invoke.pass.cpp | 5 +- .../func.invoke/invoke_constexpr.pass.cpp | 282 + .../func.memfn/member_data.compile.fail.cpp | 44 + .../func.memfn/member_data.fail.cpp | 43 - .../func.memfn/member_data.pass.cpp | 11 +- .../func.memfn/member_function.pass.cpp | 23 +- .../func.memfn/member_function_const.pass.cpp | 23 +- .../func.memfn/robust_against_adl.pass.cpp | 53 + .../func.not_fn/not_fn.pass.cpp | 309 +- .../func.require/binary_function.pass.cpp | 2 +- .../func.require/unary_function.pass.cpp | 2 +- .../func.search.bm/default.pass.cpp | 4 +- .../func.search/func.search.bm/hash.pass.cpp | 4 +- .../func.search.bm/hash.pred.pass.cpp | 4 +- .../func.search/func.search.bm/pred.pass.cpp | 4 +- .../func.search.bmh/default.pass.cpp | 4 +- .../func.search/func.search.bmh/hash.pass.cpp | 4 +- .../func.search.bmh/hash.pred.pass.cpp | 4 +- .../func.search/func.search.bmh/pred.pass.cpp | 4 +- .../func.search.default/default.pass.cpp | 23 +- .../func.search.default/default.pred.pass.cpp | 77 +- .../func.search/nothing_to_do.pass.cpp | 14 - .../func.wrap.func/addressof.pass.cpp | 32 + .../derive_from.compile.fail.cpp | 26 + .../func.wrap.func/derive_from.fail.cpp | 26 - .../func.wrap.func/derive_from.pass.cpp | 4 +- .../func.wrap.func.alg/swap.pass.cpp | 35 +- .../func.wrap.func.cap/operator_bool.pass.cpp | 7 + .../func.wrap.func.con/F.pass.cpp | 20 +- .../func.wrap.func.con/F_assign.pass.cpp | 35 +- .../func.wrap.func.con/F_incomplete.pass.cpp | 3 + .../func.wrap.func.con/F_nullptr.pass.cpp | 11 +- .../func.wrap.func.con/alloc.fail.cpp | 26 - .../func.wrap.func.con/alloc.pass.cpp | 5 +- .../func.wrap.func.con/alloc.verify.cpp | 28 + .../func.wrap.func.con/alloc_F.fail.cpp | 30 - .../func.wrap.func.con/alloc_F.pass.cpp | 26 +- .../func.wrap.func.con/alloc_F.verify.cpp | 30 + .../alloc_function.fail.cpp | 31 - .../alloc_function.pass.cpp | 41 +- .../alloc_function.verify.cpp | 30 + .../func.wrap.func.con/alloc_nullptr.fail.cpp | 28 - .../func.wrap.func.con/alloc_nullptr.pass.cpp | 5 +- .../alloc_nullptr.verify.cpp | 28 + .../alloc_rfunction.fail.cpp | 61 - .../alloc_rfunction.pass.cpp | 58 +- .../alloc_rfunction.verify.cpp | 59 + .../func.wrap.func.con/copy_assign.pass.cpp | 48 +- .../func.wrap.func.con/copy_move.pass.cpp | 78 +- .../func.wrap.func.con/deduct_F.fail.cpp | 7 +- .../func.wrap.func.con/deduct_F.pass.cpp | 8 +- .../func.wrap.func.con/deduct_ptr.pass.cpp | 8 +- .../func.wrap.func.con/default.pass.cpp | 3 + .../func.wrap.func.con/nullptr_t.pass.cpp | 3 + .../nullptr_t_assign.pass.cpp | 14 +- ...nvoke.fail.cpp => invoke.compile.fail.cpp} | 0 .../func.wrap.func.inv/invoke.pass.cpp | 16 + .../assign_F_alloc.pass.cpp | 3 + .../func.wrap.func.mod/swap.pass.cpp | 50 +- .../operator_==.pass.cpp | 3 + .../func.wrap.func.targ/target.pass.cpp | 5 + .../func.wrap.func.targ/target_type.pass.cpp | 5 + .../noncopyable_return_type.pass.cpp | 146 + .../robust_against_adl.pass.cpp | 53 + .../func.wrap/func.wrap.func/types.pass.cpp | 11 + .../func.wrap/nothing_to_do.pass.cpp | 13 - .../logical.operations/logical_and.pass.cpp | 4 + .../logical.operations/logical_not.pass.cpp | 4 + .../logical.operations/logical_or.pass.cpp | 4 + .../logical.operations/transparent.pass.cpp | 2 +- .../binary_negate.depr_in_cxx17.fail.cpp | 33 - .../binary_negate.depr_in_cxx17.verify.cpp | 32 + .../negators/binary_negate.pass.cpp | 5 +- .../negators/not1.depr_in_cxx17.fail.cpp | 31 - .../negators/not1.depr_in_cxx17.verify.cpp | 30 + .../function.objects/negators/not1.pass.cpp | 5 +- .../negators/not2.depr_in_cxx17.fail.cpp | 32 - .../negators/not2.depr_in_cxx17.verify.cpp | 31 + .../function.objects/negators/not2.pass.cpp | 5 +- .../unary_negate.depr_in_cxx17.fail.cpp | 32 - .../unary_negate.depr_in_cxx17.verify.cpp | 31 + .../negators/unary_negate.pass.cpp | 5 +- .../range.cmp/equal_to.pass.cpp | 65 + .../range.cmp/greater.pass.cpp | 64 + .../range.cmp/greater_equal.pass.cpp | 64 + .../function.objects/range.cmp/less.pass.cpp | 64 + .../range.cmp/less_equal.pass.cpp | 65 + .../range.cmp/not_equal_to.pass.cpp | 76 + .../refwrap.assign/copy_assign.pass.cpp | 20 + .../refwrap.const/ctor.incomplete.pass.cpp | 5 +- .../refwrap/refwrap.const/deduct.pass.cpp | 31 + .../refwrap.const/type_conv_ctor.pass.cpp | 76 + .../refwrap.const/type_conv_ctor2.pass.cpp | 65 + .../refwrap.const/type_ctor.compile.fail.cpp | 23 + .../refwrap/refwrap.const/type_ctor.fail.cpp | 25 - .../refwrap/refwrap.const/type_ctor.pass.cpp | 17 + .../refwrap.helpers/cref.incomplete.pass.cpp | 5 +- .../refwrap/refwrap.helpers/cref_1.pass.cpp | 15 +- .../refwrap/refwrap.helpers/cref_2.pass.cpp | 24 +- .../refwrap/refwrap.helpers/lwg3146.pass.cpp | 66 + .../refwrap.helpers/ref.incomplete.pass.cpp | 5 +- .../refwrap.helpers/ref_1.compile.fail.cpp | 29 + .../refwrap/refwrap.helpers/ref_1.fail.cpp | 30 - .../refwrap/refwrap.helpers/ref_1.pass.cpp | 15 +- .../refwrap/refwrap.helpers/ref_2.pass.cpp | 33 +- ...nvoke.fail.cpp => invoke.compile.fail.cpp} | 0 .../invoke.incomplete.compile.fail.cpp | 38 + .../refwrap.invoke/invoke.incomplete.fail.cpp | 37 - .../robust_against_adl.pass.cpp | 49 + .../refwrap/unwrap_ref_decay.pass.cpp | 2 +- .../refwrap/unwrap_reference.pass.cpp | 2 +- .../refwrap/weak_result.pass.cpp | 2 + .../unord.hash/enabled_hashes.pass.cpp | 2 +- .../{enum.fail.cpp => enum.compile.fail.cpp} | 0 .../function.objects/unord.hash/enum.pass.cpp | 10 +- .../unord.hash/floating.pass.cpp | 8 +- .../unord.hash/integral.pass.cpp | 12 +- .../unord.hash/non_enum.pass.cpp | 2 +- .../unord.hash/pointer.pass.cpp | 10 +- .../intseq.general/integer_seq.pass.cpp | 2 +- .../integer_seq.compile.fail.cpp | 33 + .../intseq/intseq.intseq/integer_seq.fail.cpp | 41 - .../intseq/intseq.intseq/integer_seq.pass.cpp | 2 +- .../intseq.make/make_integer_seq.fail.cpp | 8 +- .../intseq.make/make_integer_seq.pass.cpp | 2 +- ...make_integer_seq_fallback.compile.fail.cpp | 20 + .../make_integer_seq_fallback.fail.cpp | 20 - .../make_integer_seq_fallback.pass.cpp | 2 +- .../utilities/intseq/nothing_to_do.pass.cpp | 13 - .../allocator.tag/allocator_arg.fail.cpp | 6 +- .../allocate.fail.cpp | 52 - .../allocate.pass.cpp | 42 +- .../allocate.verify.cpp | 51 + .../allocate_hint.pass.cpp | 76 +- .../construct.pass.cpp | 147 +- .../deallocate.pass.cpp | 57 +- .../allocator.traits.members/destroy.pass.cpp | 147 +- .../max_size.pass.cpp | 19 +- ...ct_on_container_copy_construction.pass.cpp | 21 +- .../allocator.uses/nothing_to_do.pass.cpp | 13 - .../PR50299.compile.pass.cpp | 20 + .../default.allocator/allocator.ctor.pass.cpp | 44 +- .../default.allocator/allocator.dtor.pass.cpp | 40 + .../allocator.globals/eq.pass.cpp | 19 +- .../allocator.members/address.pass.cpp | 42 - .../allocate.constexpr.size.verify.cpp | 40 + .../allocator.members/allocate.fail.cpp | 29 - .../allocator.members/allocate.pass.cpp | 46 +- .../allocator.members/allocate.size.pass.cpp | 19 +- .../allocator.members/allocate.verify.cpp | 27 + .../allocator.members/construct.pass.cpp | 144 - .../allocator.members/max_size.pass.cpp | 30 - .../allocator_pointers.pass.cpp | 6 +- ...cator_types.deprecated_in_cxx17.verify.cpp | 52 + .../allocator_types.pass.cpp | 68 +- ...llocator_types.removed_in_cxx20.verify.cpp | 47 + .../allocator_types.void.compile.pass.cpp | 35 + .../default.allocator/allocator_void.pass.cpp | 39 - .../pointer.conversion/to_address.pass.cpp | 184 +- .../to_address_on_funcptr.verify.cpp | 22 + .../to_address_on_function.verify.cpp | 22 + .../to_address_std_iterators.pass.cpp | 54 + .../memory/pointer.traits/pointer_to.pass.cpp | 32 +- .../memory/specialized.algorithms/buffer.h | 25 + .../memory/specialized.algorithms/counted.h | 85 + .../nothing_to_do.pass.cpp | 13 - ...il.cpp => addressof.temp.compile.fail.cpp} | 0 .../constexpr_addressof.pass.cpp | 3 +- .../construct_at.pass.cpp | 125 + .../ranges_construct_at.pass.cpp | 139 + .../specialized.destroy/destroy.pass.cpp | 116 +- .../specialized.destroy/destroy_at.pass.cpp | 172 +- .../specialized.destroy/destroy_n.pass.cpp | 121 +- .../ranges_destroy.pass.cpp | 222 + .../ranges_destroy_at.pass.cpp | 160 + .../ranges_destroy_n.pass.cpp | 144 + ...s_uninitialized_default_construct.pass.cpp | 193 + ...uninitialized_default_construct_n.pass.cpp | 92 + .../uninitialized_default_construct.pass.cpp | 23 +- ...uninitialized_default_construct_n.pass.cpp | 24 +- ...ges_uninitialized_value_construct.pass.cpp | 213 + ...s_uninitialized_value_construct_n.pass.cpp | 111 + .../uninitialized_value_construct.pass.cpp | 2 +- .../uninitialized_value_construct_n.pass.cpp | 2 +- .../ranges_uninitialized_copy.pass.cpp | 374 + .../ranges_uninitialized_copy_n.pass.cpp | 152 + .../ranges_uninitialized_fill_n.pass.cpp | 120 + .../ranges_uninitialized_fill.pass.cpp | 232 + .../ranges_uninitialized_move.pass.cpp | 428 + .../ranges_uninitialized_move_n.pass.cpp | 204 + .../uninitialized_move.pass.cpp | 4 +- .../uninitialized_move_n.pass.cpp | 4 +- .../storage.iterator/deprecated.verify.cpp | 17 + .../raw_storage_iterator.base.pass.cpp | 17 +- .../raw_storage_iterator.pass.cpp | 11 +- .../storage.iterator/types.compile.pass.cpp | 32 + .../temporary.buffer/overaligned.pass.cpp | 8 +- ...rator_concept_conformance.compile.pass.cpp | 29 + .../unique.ptr/unique.ptr.special/io.fail.cpp | 6 +- .../unique.ptr/unique.ptr.special/io.pass.cpp | 4 +- .../declare_no_pointers.pass.cpp | 26 - .../declare_reachable.pass.cpp | 27 - .../get_pointer_safety.pass.cpp | 40 - .../util.smartptr/nothing_to_do.pass.cpp | 13 - .../enable_shared_from_this.pass.cpp | 5 +- .../util.smartptr.hash/enabled_hash.pass.cpp | 4 +- .../hash_shared_ptr.pass.cpp | 6 +- .../hash_unique_ptr.pass.cpp | 9 +- .../atomic_compare_exchange_strong.pass.cpp | 9 +- ..._compare_exchange_strong_explicit.pass.cpp | 9 +- .../atomic_compare_exchange_weak.pass.cpp | 7 +- ...ic_compare_exchange_weak_explicit.pass.cpp | 9 +- .../atomic_exchange.pass.cpp | 7 +- .../atomic_exchange_explicit.pass.cpp | 9 +- .../atomic_is_lock_free.pass.cpp | 2 +- .../atomic_load.pass.cpp | 7 +- .../atomic_load_explicit.pass.cpp | 9 +- .../atomic_store.pass.cpp | 7 +- .../atomic_store_explicit.pass.cpp | 9 +- ...rator_concept_conformance.compile.pass.cpp | 29 + .../util.smartptr.shared/types.pass.cpp | 46 +- .../get_deleter.pass.cpp | 2 + .../auto_ptr_Y.pass.cpp | 4 +- .../shared_ptr.pass.cpp | 2 +- .../shared_ptr_Y.pass.cpp | 22 +- .../shared_ptr_Y_rv.pass.cpp | 25 +- .../shared_ptr_rv.pass.cpp | 4 +- .../unique_ptr_Y.pass.cpp | 92 +- .../const_pointer_cast.pass.cpp | 12 +- .../dynamic_pointer_cast.pass.cpp | 14 +- .../reinterpret_pointer_cast.pass.cpp | 75 + .../static_pointer_cast.pass.cpp | 18 +- .../auto_ptr.pass.cpp | 42 +- .../deduction.pass.cpp | 60 + .../default.pass.cpp | 20 +- .../nullptr_t_deleter.pass.cpp | 4 +- .../nullptr_t_deleter_allocator.pass.cpp | 23 +- ...nullptr_t_deleter_allocator_throw.pass.cpp | 11 +- .../nullptr_t_deleter_throw.pass.cpp | 2 +- .../pointer.pass.cpp | 25 +- .../pointer_deleter.pass.cpp | 56 +- .../pointer_deleter_allocator.pass.cpp | 78 +- .../pointer_deleter_allocator_throw.pass.cpp | 15 +- .../pointer_deleter_throw.pass.cpp | 3 +- .../pointer_throw.pass.cpp | 3 +- .../shared_ptr_Y.pass.cpp | 60 +- .../shared_ptr_Y_rv.pass.cpp | 25 +- .../shared_ptr_copy_move.fail.cpp | 52 + .../shared_ptr_pointer.pass.cpp | 39 +- .../shared_ptr_rv.pass.cpp | 2 +- .../unique_ptr.pass.cpp | 141 +- .../weak_ptr.pass.cpp | 14 +- ...locate_shared.explicit_conversion.pass.cpp | 32 + .../allocate_shared.pass.cpp | 38 +- .../allocate_shared_construct.pass.cpp | 176 + .../make_shared.pass.cpp | 36 +- ...p => make_shared.private.compile.fail.cpp} | 0 .../make_shared.protected.fail.cpp | 30 - .../make_shared.volatile.pass.cpp | 64 - .../util.smartptr.shared.io/io.pass.cpp | 2 + .../util.smartptr.shared.mod/reset.pass.cpp | 2 +- .../reset_pointer.pass.cpp | 14 +- .../reset_pointer_deleter.pass.cpp | 22 +- .../reset_pointer_deleter_allocator.pass.cpp | 43 +- .../op_arrow.fail.cpp | 34 + .../util.smartptr.shared.obs/op_bool.pass.cpp | 35 +- .../op_bracket.fail.cpp | 28 + .../op_bracket.pass.cpp | 51 + .../util.smartptr.weak/types.pass.cpp | 26 +- .../owner_less.pass.cpp | 6 + .../shared_ptr_Y.pass.cpp | 20 +- .../weak_ptr.pass.cpp | 2 +- .../weak_ptr_Y.pass.cpp | 34 +- .../shared_ptr_Y.pass.cpp | 19 +- .../shared_ptr_deduction.pass.cpp | 33 + .../weak_ptr.pass.cpp | 2 +- .../weak_ptr_Y.pass.cpp | 23 +- ...ail.cpp => not_less_than.compile.fail.cpp} | 0 .../is_constant_evaluated.fail.cpp | 3 +- .../is_constant_evaluated.pass.cpp | 19 +- .../meta/meta.logical/conjunction.pass.cpp | 2 +- .../meta/meta.logical/disjunction.pass.cpp | 2 +- .../meta/meta.logical/negation.pass.cpp | 2 +- .../meta/meta.rel/is_base_of_union.pass.cpp | 9 - .../meta/meta.rel/is_convertible.pass.cpp | 14 +- .../meta.rel/is_convertible_fallback.pass.cpp | 3 +- .../meta/meta.rel/is_invocable.pass.cpp | 2 +- .../meta.rel/is_nothrow_convertible.pass.cpp | 2 +- .../meta.rel/is_nothrow_invocable.pass.cpp | 26 +- .../utilities/meta/meta.rel/is_same.pass.cpp | 11 + .../meta.trans.other/aligned_storage.pass.cpp | 44 +- .../aligned_union.compile.fail.cpp | 24 + .../meta.trans.other/aligned_union.fail.cpp | 24 - .../common_reference.compile.pass.cpp | 202 + .../meta.trans.other/common_type.pass.cpp | 117 +- ...if.fail.cpp => enable_if.compile.fail.cpp} | 0 .../enable_if2.compile.fail.cpp | 21 + .../meta.trans.other/enable_if2.fail.cpp | 21 - .../meta.trans.other/remove_cvref.pass.cpp | 2 +- .../result_of.deprecated.verify.cpp | 20 + .../meta.trans.other/result_of.pass.cpp | 6 +- .../meta.trans.other/result_of11.pass.cpp | 12 +- .../meta.trans.other/type_identity.pass.cpp | 2 +- .../meta.trans.other/underlying_type.fail.cpp | 8 +- .../meta.trans.sign/make_signed.pass.cpp | 4 +- .../meta.trans.sign/make_unsigned.pass.cpp | 4 +- .../meta/meta.trans/nothing_to_do.pass.cpp | 13 - .../alignment_of.pass.cpp | 4 +- .../meta.unary.prop.query/void_t.pass.cpp | 4 +- .../meta.unary.cat/function.pass.cpp | 2 - .../meta.unary.cat/integral.pass.cpp | 2 +- .../meta.unary.cat/is_null_pointer.pass.cpp | 2 +- ...ber_function_pointer_no_variadics.pass.cpp | 84 - .../meta.unary.cat/nullptr.pass.cpp | 2 +- .../meta.unary.comp/integral.pass.cpp | 2 +- .../meta.unary.comp/is_arithmetic.pass.cpp | 9 + .../meta.unary.comp/is_bounded_array.pass.cpp | 2 +- .../is_unbounded_array.pass.cpp | 4 +- ...has_unique_object_representations.pass.cpp | 3 +- .../meta.unary.prop/is_aggregate.pass.cpp | 6 +- .../meta.unary.prop/is_constructible.pass.cpp | 59 +- .../meta.unary.prop/is_final.pass.cpp | 2 +- .../is_literal_type.deprecated.fail.cpp | 24 + .../meta.unary.prop/is_literal_type.pass.cpp | 3 + .../is_nothrow_swappable.pass.cpp | 2 +- .../is_nothrow_swappable_with.pass.cpp | 2 +- .../meta.unary.prop/is_scoped_enum.pass.cpp | 120 + .../meta.unary.prop/is_signed.pass.cpp | 78 +- .../meta.unary.prop/is_swappable.pass.cpp | 2 +- .../is_swappable_with.pass.cpp | 2 +- .../is_trivially_copyable.pass.cpp | 4 - .../is_trivially_destructible.pass.cpp | 1 - .../meta.unary.prop/is_unsigned.pass.cpp | 78 +- .../meta/meta.unary/nothing_to_do.pass.cpp | 13 - test/std/utilities/nothing_to_do.pass.cpp | 13 - ...rator_concept_conformance.compile.pass.cpp | 22 + .../default.pass.cpp | 5 +- .../derive.pass.cpp | 6 +- .../optional.comp_with_t/equal.pass.cpp | 2 +- .../optional.comp_with_t/greater.pass.cpp | 2 +- .../greater_equal.pass.cpp | 2 +- .../optional.comp_with_t/less_equal.pass.cpp | 2 +- .../optional.comp_with_t/less_than.pass.cpp | 2 +- .../optional.comp_with_t/not_equal.pass.cpp | 2 +- .../optional.hash/enabled_hash.pass.cpp | 2 +- .../optional/optional.hash/hash.pass.cpp | 4 +- .../optional.monadic/and_then.pass.cpp | 263 + .../optional.monadic/or_else.pass.cpp | 73 + .../optional.monadic/transform.pass.cpp | 206 + .../optional/optional.nullops/equal.pass.cpp | 2 +- .../optional.nullops/greater.pass.cpp | 2 +- .../optional.nullops/greater_equal.pass.cpp | 2 +- .../optional.nullops/less_equal.pass.cpp | 2 +- .../optional.nullops/less_than.pass.cpp | 2 +- .../optional.nullops/not_equal.pass.cpp | 2 +- .../nullopt_t.compile.fail.cpp | 26 + .../optional.nullopt/nullopt_t.fail.cpp | 26 - .../optional.nullopt/nullopt_t.pass.cpp | 2 +- .../assign_value.pass.cpp | 4 +- .../const_optional_U.pass.cpp | 6 +- .../optional.object.assign/copy.pass.cpp | 3 +- .../optional.object.assign/emplace.pass.cpp | 55 +- .../emplace_initializer_list.pass.cpp | 62 +- .../optional.object.assign/move.pass.cpp | 2 +- .../optional.object.assign/nullopt_t.pass.cpp | 40 +- .../optional_U.pass.cpp | 145 +- .../optional.object.ctor/U.pass.cpp | 5 +- .../optional.object.ctor/const_T.pass.cpp | 5 +- .../const_optional_U.pass.cpp | 73 +- .../optional.object.ctor/copy.pass.cpp | 2 +- .../optional.object.ctor/ctor.fail.cpp | 8 +- .../optional.object.ctor/deduct.fail.cpp | 16 +- .../optional.object.ctor/deduct.pass.cpp | 41 +- .../optional.object.ctor/default.pass.cpp | 2 +- ...empty_in_place_t_does_not_clobber.pass.cpp | 2 +- .../explicit_const_optional_U.pass.cpp | 62 +- .../explicit_optional_U.pass.cpp | 25 +- .../optional.object.ctor/in_place_t.pass.cpp | 2 +- .../initializer_list.pass.cpp | 2 +- .../optional.object.ctor/move.fail.cpp | 2 +- .../optional.object.ctor/move.pass.cpp | 5 +- .../optional.object.ctor/nullopt_t.pass.cpp | 2 +- .../optional.object.ctor/optional_U.pass.cpp | 44 +- .../optional.object.ctor/rvalue_T.pass.cpp | 14 +- .../optional.object.dtor/dtor.pass.cpp | 6 +- .../optional.object.mod/reset.pass.cpp | 13 +- .../optional.object.observe/bool.pass.cpp | 2 +- .../dereference.pass.cpp | 16 +- .../dereference_const.pass.cpp | 16 +- .../dereference_const_rvalue.pass.cpp | 16 +- .../dereference_rvalue.pass.cpp | 16 +- .../has_value.pass.cpp | 2 +- .../optional.object.observe/op_arrow.pass.cpp | 15 +- .../op_arrow_const.pass.cpp | 15 +- .../optional.object.observe/value.pass.cpp | 5 +- .../value_const.compile.fail.cpp | 34 + .../value_const.fail.cpp | 34 - .../value_const.pass.cpp | 5 +- .../value_const_rvalue.pass.cpp | 5 +- .../optional.object.observe/value_or.pass.cpp | 2 +- .../value_or_const.pass.cpp | 2 +- .../value_rvalue.pass.cpp | 5 +- .../optional.object.swap/swap.pass.cpp | 119 +- ...onal_requires_destructible_object.fail.cpp | 2 +- .../optional.object/special_members.pass.cpp | 2 +- .../optional.object/triviality.pass.cpp | 2 +- .../optional/optional.object/types.pass.cpp | 2 +- .../optional/optional.relops/equal.pass.cpp | 2 +- .../optional.relops/greater_equal.pass.cpp | 2 +- .../optional.relops/greater_than.pass.cpp | 2 +- .../optional.relops/less_equal.pass.cpp | 2 +- .../optional.relops/less_than.pass.cpp | 2 +- .../optional.relops/not_equal.pass.cpp | 2 +- .../optional.specalg/make_optional.pass.cpp | 6 +- .../make_optional_explicit.pass.cpp | 2 +- ...ptional_explicit_initializer_list.pass.cpp | 2 +- .../optional/optional.specalg/swap.pass.cpp | 4 +- .../optional.syn/optional_in_place_t.fail.cpp | 2 +- ...ptional_includes_initializer_list.pass.cpp | 2 +- .../optional.syn/optional_nullopt_t.fail.cpp | 2 +- ...dd.fail.cpp => ratio_add.compile.fail.cpp} | 0 ...fail.cpp => ratio_divide.compile.fail.cpp} | 0 ...il.cpp => ratio_multiply.compile.fail.cpp} | 0 ...il.cpp => ratio_subtract.compile.fail.cpp} | 0 ...atio1.fail.cpp => ratio1.compile.fail.cpp} | 0 ...atio2.fail.cpp => ratio2.compile.fail.cpp} | 0 ...atio3.fail.cpp => ratio3.compile.fail.cpp} | 0 .../unique.ptr/nothing_to_do.pass.cpp | 13 - .../unique.ptr.asgn/move.pass.cpp | 13 +- .../unique.ptr.asgn/move_convert.pass.cpp | 4 +- .../move_convert.runtime.pass.cpp | 2 +- .../move_convert.single.pass.cpp | 2 +- .../unique.ptr.ctor/auto_pointer.pass.cpp | 2 +- .../unique.ptr.ctor/deduct.pass.cpp | 45 + .../unique.ptr.ctor/default.pass.cpp | 5 + .../unique.ptr.ctor/move.pass.cpp | 4 +- .../unique.ptr.ctor/move_convert.pass.cpp | 4 +- .../move_convert.runtime.pass.cpp | 2 +- .../move_convert.single.pass.cpp | 2 +- .../unique.ptr.ctor/null.pass.cpp | 2 +- .../unique.ptr.ctor/nullptr.pass.cpp | 7 +- .../unique.ptr.ctor/pointer.pass.cpp | 10 +- .../reset.runtime.fail.cpp | 1 + .../unique.ptr.modifiers/reset_self.pass.cpp | 2 +- .../dereference.runtime.fail.cpp | 25 - .../dereference.verify.cpp | 25 + .../op_arrow.runtime.fail.cpp | 33 - .../unique.ptr.observers/op_arrow.verify.cpp | 33 + .../make_unique.array.pass.cpp | 2 +- ...pp => make_unique.array1.compile.fail.cpp} | 0 ...pp => make_unique.array2.compile.fail.cpp} | 0 ...pp => make_unique.array3.compile.fail.cpp} | 0 ...pp => make_unique.array4.compile.fail.cpp} | 0 .../make_unique.single.pass.cpp | 2 +- .../unique.ptr.dltr/nothing_to_do.pass.cpp | 13 - .../convert_ctor.pass.cpp | 2 +- ...e.fail.cpp => incomplete.compile.fail.cpp} | 0 .../{void.fail.cpp => void.compile.fail.cpp} | 0 ...fail.cpp => convert_ctor.compile.fail.cpp} | 0 ...e.fail.cpp => incomplete.compile.fail.cpp} | 0 .../unique.ptr/unique.ptr.special/eq.pass.cpp | 2 +- .../unique.ptr.special/rel.pass.cpp | 2 +- .../bitset.cons/char_ptr_ctor.pass.cpp | 8 +- .../bitset.cons/default.pass.cpp | 6 +- .../bitset.cons/string_ctor.pass.cpp | 47 +- .../bitset.cons/ull_ctor.pass.cpp | 6 +- .../bitset.hash/enabled_hash.pass.cpp | 2 +- .../bitset.members/all.pass.cpp | 14 +- .../bitset.members/any.pass.cpp | 14 +- .../bitset.members/count.pass.cpp | 45 +- .../bitset.members/flip_all.pass.cpp | 41 +- .../flip_one.out_of_range.pass.cpp | 34 + .../bitset.members/flip_one.pass.cpp | 81 +- .../bitset.members/index.pass.cpp | 94 +- .../bitset.members/index_const.pass.cpp | 40 +- .../bitset.members/left_shift.pass.cpp | 40 +- .../bitset.members/left_shift_eq.pass.cpp | 50 +- .../bitset.members/none.pass.cpp | 14 +- .../bitset.members/not_all.pass.cpp | 39 +- .../bitset.members/op_and_eq.pass.cpp | 45 +- .../bitset.members/op_eq_eq.pass.cpp | 46 +- .../bitset.members/op_or_eq.pass.cpp | 45 +- .../bitset.members/op_xor_eq.pass.cpp | 45 +- .../bitset.members/reset_all.pass.cpp | 17 +- .../reset_one.out_of_range.pass.cpp | 34 + .../bitset.members/reset_one.pass.cpp | 64 +- .../bitset.members/right_shift.pass.cpp | 40 +- .../bitset.members/right_shift_eq.pass.cpp | 50 +- .../bitset.members/set_all.pass.cpp | 17 +- .../set_one.out_of_range.pass.cpp | 34 + .../bitset.members/set_one.pass.cpp | 72 +- .../bitset.members/size.pass.cpp | 8 +- .../bitset.members/test.out_of_range.pass.cpp | 37 + .../bitset.members/test.pass.cpp | 71 +- .../bitset.members/to_string.pass.cpp | 210 +- .../bitset.members/to_ullong.pass.cpp | 39 +- .../bitset.members/to_ulong.pass.cpp | 39 +- .../bitset.operators/op_and.pass.cpp | 41 +- .../bitset.operators/op_not.pass.cpp | 41 +- .../bitset.operators/op_or.pass.cpp | 41 +- .../bitset.operators/stream_in.pass.cpp | 2 + .../bitset.operators/stream_out.pass.cpp | 2 + .../template.bitset/bitset_test_cases.h | 177 + .../template.bitset/includes.pass.cpp | 1 - test/std/utilities/time/clock.h | 2 +- .../utilities/time/date.time/ctime.pass.cpp | 65 - test/std/utilities/time/days.pass.cpp | 5 +- test/std/utilities/time/hours.pass.cpp | 3 +- test/std/utilities/time/microseconds.pass.cpp | 3 +- test/std/utilities/time/milliseconds.pass.cpp | 3 +- test/std/utilities/time/minutes.pass.cpp | 3 +- test/std/utilities/time/months.pass.cpp | 6 +- test/std/utilities/time/nanoseconds.pass.cpp | 3 +- test/std/utilities/time/rep.h | 2 +- test/std/utilities/time/seconds.pass.cpp | 3 +- .../time/time.cal/nothing_to_do.pass.cpp | 13 - .../time.cal.day.members/ctor.pass.cpp | 6 +- .../time.cal.day.members/decrement.pass.cpp | 10 +- .../time.cal.day.members/increment.pass.cpp | 10 +- .../time.cal.day.members/ok.pass.cpp | 2 +- .../plus_minus_equal.pass.cpp | 12 +- .../comparisons.pass.cpp | 4 +- .../time.cal.day.nonmembers/literals.fail.cpp | 4 +- .../time.cal.day.nonmembers/literals.pass.cpp | 7 +- .../time.cal.day.nonmembers/minus.pass.cpp | 2 +- .../time.cal.day.nonmembers/plus.pass.cpp | 2 +- .../streaming.pass.cpp | 57 - .../time/time.cal/time.cal.day/types.pass.cpp | 2 +- .../time.cal/time.cal.last/types.pass.cpp | 2 +- .../time.cal.md.members/ctor.pass.cpp | 2 +- .../time.cal.md.members/day.pass.cpp | 2 +- .../time.cal.md.members/month.pass.cpp | 2 +- .../time.cal.md.members/ok.pass.cpp | 4 +- .../comparisons.pass.cpp | 6 +- .../time.cal.md.nonmembers/streaming.pass.cpp | 42 - .../time/time.cal/time.cal.md/types.pass.cpp | 2 +- .../time.cal.mdlast/comparisons.pass.cpp | 12 +- .../time.cal/time.cal.mdlast/ctor.pass.cpp | 2 +- .../time.cal/time.cal.mdlast/month.pass.cpp | 2 +- .../time/time.cal/time.cal.mdlast/ok.pass.cpp | 4 +- .../time.cal.mdlast/streaming.pass.cpp | 35 - .../time.cal/time.cal.mdlast/types.pass.cpp | 2 +- .../time.cal.month.members/ctor.pass.cpp | 2 +- .../time.cal.month.members/decrement.pass.cpp | 10 +- .../time.cal.month.members/increment.pass.cpp | 10 +- .../time.cal.month.members/ok.pass.cpp | 2 +- .../plus_minus_equal.pass.cpp | 14 +- .../comparisons.pass.cpp | 8 +- .../literals.pass.cpp | 2 +- .../time.cal.month.nonmembers/minus.pass.cpp | 17 +- .../time.cal.month.nonmembers/plus.pass.cpp | 12 +- .../streaming.pass.cpp | 54 - .../time.cal/time.cal.month/types.pass.cpp | 2 +- .../time.cal.mwd.members/ctor.pass.cpp | 2 +- .../time.cal.mwd.members/month.pass.cpp | 4 +- .../time.cal.mwd.members/ok.pass.cpp | 6 +- .../weekday_indexed.pass.cpp | 2 +- .../comparisons.pass.cpp | 2 +- .../streaming.pass.cpp | 37 - .../time/time.cal/time.cal.mwd/types.pass.cpp | 2 +- .../time.cal.mwdlast.members/ctor.pass.cpp | 10 +- .../time.cal.mwdlast.members/month.pass.cpp | 2 +- .../time.cal.mwdlast.members/ok.pass.cpp | 2 +- .../weekday_last.pass.cpp | 2 +- .../comparisons.pass.cpp | 18 +- .../streaming.pass.cpp | 38 - .../time.cal/time.cal.mwdlast/types.pass.cpp | 2 +- .../time.cal.operators/month_day.pass.cpp | 2 +- .../month_day_last.pass.cpp | 11 +- .../time.cal.operators/month_weekday.pass.cpp | 2 +- .../month_weekday_last.pass.cpp | 2 +- .../time.cal.operators/year_month.pass.cpp | 2 +- .../year_month_day.pass.cpp | 2 +- .../year_month_day_last.pass.cpp | 13 +- .../year_month_weekday.pass.cpp | 2 +- .../year_month_weekday_last.pass.cpp | 2 +- .../time.cal.wdidx.members/ctor.pass.cpp | 2 +- .../time.cal.wdidx.members/index.pass.cpp | 2 +- .../time.cal.wdidx.members/ok.pass.cpp | 6 +- .../time.cal.wdidx.members/weekday.pass.cpp | 2 +- .../comparisons.pass.cpp | 6 +- .../streaming.pass.cpp | 37 - .../time.cal/time.cal.wdidx/types.pass.cpp | 2 +- .../time.cal.wdlast.members/ctor.pass.cpp | 2 +- .../time.cal.wdlast.members/ok.pass.cpp | 2 +- .../time.cal.wdlast.members/weekday.pass.cpp | 2 +- .../comparisons.pass.cpp | 6 +- .../streaming.pass.cpp | 35 - .../time.cal/time.cal.wdlast/types.pass.cpp | 2 +- .../c_encoding.pass.cpp | 2 +- .../ctor.local_days.pass.cpp | 8 +- .../time.cal.weekday.members/ctor.pass.cpp | 6 +- .../ctor.sys_days.pass.cpp | 8 +- .../decrement.pass.cpp | 2 +- .../increment.pass.cpp | 2 +- .../iso_encoding.pass.cpp | 8 +- .../time.cal.weekday.members/ok.pass.cpp | 4 +- .../operator[].pass.cpp | 2 +- .../plus_minus_equal.pass.cpp | 2 +- .../comparisons.pass.cpp | 6 +- .../literals.pass.cpp | 2 +- .../minus.pass.cpp | 14 +- .../time.cal.weekday.nonmembers/plus.pass.cpp | 12 +- .../streaming.pass.cpp | 57 - .../time.cal/time.cal.weekday/types.pass.cpp | 2 +- .../time.cal.year.members/ctor.pass.cpp | 6 +- .../time.cal.year.members/decrement.pass.cpp | 10 +- .../time.cal.year.members/increment.pass.cpp | 10 +- .../time.cal.year.members/is_leap.pass.cpp | 4 +- .../time.cal.year.members/ok.pass.cpp | 2 +- .../time.cal.year.members/plus_minus.pass.cpp | 8 +- .../plus_minus_equal.pass.cpp | 12 +- .../comparisons.pass.cpp | 6 +- .../literals.fail.cpp | 4 +- .../literals.pass.cpp | 5 +- .../time.cal.year.nonmembers/minus.pass.cpp | 4 +- .../time.cal.year.nonmembers/plus.pass.cpp | 2 +- .../streaming.pass.cpp | 56 - .../time.cal/time.cal.year/types.pass.cpp | 2 +- .../time.cal.ym.members/ctor.pass.cpp | 2 +- .../time.cal.ym.members/month.pass.cpp | 2 +- .../time.cal.ym.members/ok.pass.cpp | 2 +- .../plus_minus_equal_month.pass.cpp | 2 +- .../plus_minus_equal_year.pass.cpp | 2 +- .../time.cal.ym.members/year.pass.cpp | 2 +- .../comparisons.pass.cpp | 12 +- .../time.cal.ym.nonmembers/minus.pass.cpp | 17 +- .../time.cal.ym.nonmembers/plus.pass.cpp | 138 +- .../time.cal.ym.nonmembers/streaming.pass.cpp | 58 - .../time/time.cal/time.cal.ym/types.pass.cpp | 2 +- .../ctor.local_days.pass.cpp | 2 +- .../time.cal.ymd.members/ctor.pass.cpp | 2 +- .../ctor.sys_days.pass.cpp | 10 +- .../ctor.year_month_day_last.pass.cpp | 2 +- .../time.cal.ymd.members/day.pass.cpp | 2 +- .../time.cal.ymd.members/month.pass.cpp | 2 +- .../time.cal.ymd.members/ok.pass.cpp | 8 +- .../op.local_days.pass.cpp | 8 +- .../time.cal.ymd.members/op.sys_days.pass.cpp | 10 +- .../plus_minus_equal_month.pass.cpp | 2 +- .../plus_minus_equal_year.pass.cpp | 2 +- .../time.cal.ymd.members/year.pass.cpp | 2 +- .../comparisons.pass.cpp | 28 +- .../time.cal.ymd.nonmembers/minus.pass.cpp | 2 +- .../time.cal.ymd.nonmembers/plus.pass.cpp | 2 +- .../streaming.pass.cpp | 59 - .../time/time.cal/time.cal.ymd/types.pass.cpp | 2 +- .../time.cal.ymdlast.members/ctor.pass.cpp | 2 +- .../time.cal.ymdlast.members/day.pass.cpp | 6 +- .../time.cal.ymdlast.members/month.pass.cpp | 2 +- .../month_day_last.pass.cpp | 2 +- .../time.cal.ymdlast.members/ok.pass.cpp | 2 +- .../op_local_days.pass.cpp | 4 +- .../op_sys_days.pass.cpp | 4 +- .../plus_minus_equal_month.pass.cpp | 2 +- .../plus_minus_equal_year.pass.cpp | 2 +- .../time.cal.ymdlast.members/year.pass.cpp | 2 +- .../comparisons.pass.cpp | 20 +- .../minus.pass.cpp | 6 +- .../time.cal.ymdlast.nonmembers/plus.pass.cpp | 2 +- .../streaming.pass.cpp | 38 - .../ctor.local_days.pass.cpp | 2 +- .../time.cal.ymwd.members/ctor.pass.cpp | 2 +- .../ctor.sys_days.pass.cpp | 2 +- .../time.cal.ymwd.members/index.pass.cpp | 2 +- .../time.cal.ymwd.members/month.pass.cpp | 2 +- .../time.cal.ymwd.members/ok.pass.cpp | 28 +- .../op.local_days.pass.cpp | 6 +- .../op.sys_days.pass.cpp | 6 +- .../plus_minus_equal_month.pass.cpp | 2 +- .../plus_minus_equal_year.pass.cpp | 2 +- .../time.cal.ymwd.members/weekday.pass.cpp | 2 +- .../weekday_indexed.pass.cpp | 2 +- .../time.cal.ymwd.members/year.pass.cpp | 2 +- .../comparisons.pass.cpp | 28 +- .../time.cal.ymwd.nonmembers/minus.pass.cpp | 2 +- .../time.cal.ymwd.nonmembers/plus.pass.cpp | 2 +- .../streaming.pass.cpp | 58 - .../time.cal/time.cal.ymwd/types.pass.cpp | 2 +- .../time.cal.ymwdlast.members/ctor.pass.cpp | 2 +- .../time.cal.ymwdlast.members/month.pass.cpp | 2 +- .../time.cal.ymwdlast.members/ok.pass.cpp | 2 +- .../op_local_days.pass.cpp | 4 +- .../op_sys_days.pass.cpp | 2 +- .../plus_minus_equal_month.pass.cpp | 2 +- .../plus_minus_equal_year.pass.cpp | 2 +- .../weekday.pass.cpp | 2 +- .../time.cal.ymwdlast.members/year.pass.cpp | 2 +- .../comparisons.pass.cpp | 28 +- .../minus.pass.cpp | 2 +- .../plus.pass.cpp | 2 +- .../streaming.pass.cpp | 39 - .../time.cal/time.cal.ymwdlast/types.pass.cpp | 2 +- .../time/time.clock/nothing_to_do.pass.cpp | 13 - .../time.clock.file/consistency.pass.cpp | 3 +- .../time.clock.file/file_time.pass.cpp | 4 +- .../time.clock/time.clock.file/now.pass.cpp | 7 +- .../time.clock.file/rep_signed.pass.cpp | 3 +- .../time.clock.file/to_from_sys.pass.cpp | 67 + .../time.clock.hires/consistency.pass.cpp | 7 +- .../time.clock.steady/consistency.pass.cpp | 7 +- .../time.clock/time.clock.steady/now.pass.cpp | 2 + .../time.clock.system/consistency.pass.cpp | 7 +- .../local_time.types.pass.cpp | 10 +- .../time.clock.system/sys.time.types.pass.cpp | 10 +- .../time/time.duration/default_ratio.pass.cpp | 1 + ...ion.fail.cpp => duration.compile.fail.cpp} | 0 ...fail.cpp => positive_num.compile.fail.cpp} | 0 ...{ratio.fail.cpp => ratio.compile.fail.cpp} | 0 .../{abs.fail.cpp => abs.compile.fail.cpp} | 0 .../time.duration.alg/abs.pass.cpp | 5 +- .../time.duration.arithmetic/op_+.pass.cpp | 2 + .../time.duration.arithmetic/op_-.pass.cpp | 2 + .../{ceil.fail.cpp => ceil.compile.fail.cpp} | 0 .../time.duration.cast/ceil.pass.cpp | 2 +- .../time.duration.cast/duration_cast.pass.cpp | 3 +- ...{floor.fail.cpp => floor.compile.fail.cpp} | 0 .../time.duration.cast/floor.pass.cpp | 2 +- ...{round.fail.cpp => round.compile.fail.cpp} | 0 .../time.duration.cast/round.pass.cpp | 2 +- ...n.fail.cpp => toduration.compile.fail.cpp} | 0 .../op_equal.pass.cpp | 1 + .../op_less.pass.cpp | 1 + ... => convert_float_to_int.compile.fail.cpp} | 0 ...l.cpp => convert_inexact.compile.fail.cpp} | 0 .../convert_inexact.pass.cpp | 1 + .../convert_int_to_float.pass.cpp | 1 + .../convert_overflow.pass.cpp | 1 + .../time.duration.cons/rep.pass.cpp | 46 +- ...{rep01.fail.cpp => rep01.compile.fail.cpp} | 0 ...{rep02.fail.cpp => rep02.compile.fail.cpp} | 0 ...{rep03.fail.cpp => rep03.compile.fail.cpp} | 0 .../time.duration.literals/literals.pass.cpp | 2 +- .../literals1.compile.fail.cpp | 18 + .../time.duration.literals/literals1.fail.cpp | 20 - .../time.duration.literals/literals1.pass.cpp | 3 +- .../literals2.compile.fail.cpp | 20 + .../time.duration.literals/literals2.fail.cpp | 21 - .../time.duration.literals/literals2.pass.cpp | 2 +- .../time.duration.nonmember/op_+.pass.cpp | 1 + .../time.duration.nonmember/op_-.pass.cpp | 1 + .../op_divide_duration.pass.cpp | 1 + ...ail.cpp => op_divide_rep.compile.fail.cpp} | 0 .../op_mod_duration.pass.cpp | 1 + ...p.fail.cpp => op_mod_rep.compile.fail.cpp} | 0 ...ail.cpp => op_times_rep1.compile.fail.cpp} | 0 ...ail.cpp => op_times_rep2.compile.fail.cpp} | 0 .../time.duration.special/max.pass.cpp | 8 +- .../time.duration.special/min.pass.cpp | 8 +- .../time.duration.special/zero.pass.cpp | 8 +- .../time/time.duration/types.pass.cpp | 1 + .../utilities/time/time.hms/hhmmss.fail.cpp | 12 +- .../time/time.hms/time.12/is_am.pass.cpp | 5 +- .../time/time.hms/time.12/is_pm.pass.cpp | 5 +- .../time/time.hms/time.12/make12.pass.cpp | 5 +- .../time/time.hms/time.12/make24.pass.cpp | 13 +- .../time.hms/time.hms.members/hours.pass.cpp | 12 +- .../time.hms.members/is_negative.pass.cpp | 10 +- .../time.hms.members/minutes.pass.cpp | 10 +- .../time.hms.members/precision.pass.cpp | 12 +- .../time.hms.members/precision_type.pass.cpp | 80 - .../time.hms.members/seconds.pass.cpp | 10 +- .../time.hms.members/subseconds.pass.cpp | 10 +- .../time.hms.members/to_duration.pass.cpp | 10 +- .../time.hms/time.hms.members/width.pass.cpp | 11 +- ...ion.fail.cpp => duration.compile.fail.cpp} | 0 .../{ceil.fail.cpp => ceil.compile.fail.cpp} | 0 .../time.point/time.point.cast/ceil.pass.cpp | 2 +- ...{floor.fail.cpp => floor.compile.fail.cpp} | 0 .../time.point/time.point.cast/floor.pass.cpp | 2 +- ...{round.fail.cpp => round.compile.fail.cpp} | 0 .../time.point/time.point.cast/round.pass.cpp | 2 +- .../time.point.cast/time_point_cast.pass.cpp | 3 +- ...n.fail.cpp => toduration.compile.fail.cpp} | 0 ...ual.fail.cpp => op_equal.compile.fail.cpp} | 0 ...less.fail.cpp => op_less.compile.fail.cpp} | 0 ...vert.fail.cpp => convert.compile.fail.cpp} | 0 .../time.point.cons/default.pass.cpp | 1 + ...ion.fail.cpp => duration.compile.fail.cpp} | 0 .../op_-duration.pass.cpp | 5 +- .../time/time.traits/nothing_to_do.pass.cpp | 13 - .../duration.pass.cpp | 2 + .../time_point.pass.cpp | 2 + test/std/utilities/time/weeks.pass.cpp | 5 +- test/std/utilities/time/years.pass.cpp | 5 +- .../tuple/tuple.general/ignore.pass.cpp | 2 +- .../tuple.general/tuple.smartptr.pass.cpp | 2 +- .../tuple/tuple.tuple/PR27375.pass.cpp | 19 + .../tuple/tuple.tuple/PR38601.pass.cpp | 31 + .../tuple/tuple.tuple/TupleFunction.pass.cpp | 2 +- .../utilities/tuple/tuple.tuple/alloc_first.h | 2 +- .../utilities/tuple/tuple.tuple/alloc_last.h | 2 +- .../tuple.tuple/tuple.apply/apply.pass.cpp | 7 +- .../tuple.apply/apply_extended_types.pass.cpp | 5 +- .../tuple.apply/apply_large_arity.pass.cpp | 2 +- .../tuple.apply/make_from_tuple.pass.cpp | 6 +- .../tuple.assign/const_pair.pass.cpp | 58 +- .../tuple.assign/convert_copy.pass.cpp | 65 +- .../tuple.assign/convert_move.pass.cpp | 194 +- .../tuple.assign/copy.compile.fail.cpp | 32 + .../tuple.tuple/tuple.assign/copy.fail.cpp | 32 - .../tuple.tuple/tuple.assign/copy.pass.cpp | 72 +- .../derived_from_tuple_like.pass.cpp | 120 + .../tuple.assign/laziness.pass.cpp | 77 + .../tuple.tuple/tuple.assign/move.pass.cpp | 66 +- .../tuple.assign/move_pair.pass.cpp | 155 +- .../tuple_array_template_depth.pass.cpp | 37 - ...855_tuple_ref_binding_diagnostics.pass.cpp | 7 +- ...PR22806_constrain_tuple_like_ctor.pass.cpp | 13 +- .../PR23256_constrain_UTypes_ctor.pass.cpp | 16 +- ...4_contains_ref_to_incomplete_type.pass.cpp | 8 +- .../tuple.tuple/tuple.cnstr/PR31384.pass.cpp | 67 +- .../tuple.cnstr/UTypes.compile.fail.cpp | 52 + .../tuple.tuple/tuple.cnstr/UTypes.fail.cpp | 52 - .../tuple.tuple/tuple.cnstr/UTypes.pass.cpp | 54 +- .../tuple.tuple/tuple.cnstr/alloc.fail.cpp | 2 +- .../tuple.tuple/tuple.cnstr/alloc.pass.cpp | 14 +- .../tuple.cnstr/alloc_UTypes.pass.cpp | 4 +- .../tuple.cnstr/alloc_const_Types.fail.cpp | 6 +- .../tuple.cnstr/alloc_const_Types.pass.cpp | 18 +- .../tuple.cnstr/alloc_const_pair.pass.cpp | 11 +- .../tuple.cnstr/alloc_convert_copy.fail.cpp | 6 +- .../tuple.cnstr/alloc_convert_copy.pass.cpp | 15 +- .../tuple.cnstr/alloc_convert_move.fail.cpp | 4 +- .../tuple.cnstr/alloc_convert_move.pass.cpp | 15 +- .../tuple.cnstr/alloc_copy.pass.cpp | 14 +- .../tuple.cnstr/alloc_move.pass.cpp | 14 +- .../tuple.cnstr/alloc_move_pair.pass.cpp | 11 +- .../cnstr_with_any.compile.pass.cpp | 76 + .../tuple.cnstr/const_Types.fail.cpp | 2 +- .../tuple.cnstr/const_Types.pass.cpp | 24 +- .../tuple.cnstr/const_Types2.compile.fail.cpp | 28 + .../tuple.cnstr/const_Types2.fail.cpp | 28 - .../tuple.cnstr/const_pair.pass.cpp | 2 +- .../tuple.cnstr/convert_copy.pass.cpp | 2 +- .../tuple.cnstr/convert_move.pass.cpp | 2 +- .../tuple.cnstr/copy.compile.fail.cpp | 31 + .../tuple.tuple/tuple.cnstr/copy.fail.cpp | 31 - .../tuple.tuple/tuple.cnstr/copy.pass.cpp | 2 +- .../tuple.tuple/tuple.cnstr/deduct.pass.cpp | 9 +- .../tuple.tuple/tuple.cnstr/default.fail.cpp | 6 +- .../tuple.cnstr/default.lazy.verify.cpp | 26 + .../tuple.tuple/tuple.cnstr/default.pass.cpp | 2 +- .../tuple.tuple/tuple.cnstr/dtor.pass.cpp | 2 +- .../empty_tuple_trivial.compile.pass.cpp | 14 + .../tuple.tuple/tuple.cnstr/move.pass.cpp | 4 +- .../tuple.cnstr/move_pair.pass.cpp | 11 +- .../tuple.cnstr/recursion_depth.pass.cpp | 34 + .../tuple.cnstr/test_lazy_sfinae.pass.cpp | 76 +- .../tuple_array_template_depth.pass.cpp | 39 - .../tuple.creation/forward_as_tuple.pass.cpp | 2 +- .../tuple.creation/make_tuple.pass.cpp | 50 +- .../tuple.tuple/tuple.creation/tie.pass.cpp | 35 +- .../tuple.creation/tuple_cat.pass.cpp | 18 +- .../tuple.elem/get_const.compile.fail.cpp | 42 + .../tuple.tuple/tuple.elem/get_const.fail.cpp | 42 - .../tuple.tuple/tuple.elem/get_const.pass.cpp | 2 +- .../tuple.elem/get_const_rv.fail.cpp | 2 +- .../tuple.elem/get_const_rv.pass.cpp | 2 +- .../tuple.elem/get_non_const.pass.cpp | 2 +- .../tuple.tuple/tuple.elem/get_rv.pass.cpp | 2 +- .../tuple.elem/tuple.by.type.fail.cpp | 2 +- .../tuple.elem/tuple.by.type.pass.cpp | 2 +- .../tuple.helper/tuple_element.fail.cpp | 2 +- .../tuple.helper/tuple_element.pass.cpp | 2 +- .../tuple.helper/tuple_size.fail.cpp | 2 +- .../tuple.helper/tuple_size.pass.cpp | 2 +- .../tuple_size_incomplete.fail.cpp | 2 +- .../tuple_size_incomplete.pass.cpp | 2 +- .../tuple_size_structured_bindings.pass.cpp | 3 +- .../tuple.helper/tuple_size_v.fail.cpp | 2 +- .../tuple.helper/tuple_size_v.pass.cpp | 2 +- .../tuple_size_value_sfinae.pass.cpp | 2 +- .../tuple/tuple.tuple/tuple.rel/eq.pass.cpp | 2 +- .../tuple/tuple.tuple/tuple.rel/lt.pass.cpp | 2 +- .../size_incompatible_comparison.verify.cpp | 29 + ...ze_incompatible_three_way.compile.pass.cpp | 28 + .../tuple.tuple/tuple.rel/three_way.pass.cpp | 237 + .../tuple.special/non_member_swap.pass.cpp | 2 +- .../tuple.swap/member_swap.pass.cpp | 18 +- .../tuple.traits/uses_allocator.pass.cpp | 2 +- .../type.index.hash/enabled_hash.pass.cpp | 4 +- .../type.index/type.index.hash/hash.pass.cpp | 2 + .../type.index.members/ctor.pass.cpp | 2 + .../type.index/type.index.members/eq.pass.cpp | 2 + .../type.index.members/hash_code.pass.cpp | 2 + .../type.index/type.index.members/lt.pass.cpp | 2 + .../type.index.members/name.pass.cpp | 2 + .../type.index.overview/copy_assign.pass.cpp | 2 + .../type.index.overview/copy_ctor.pass.cpp | 2 + .../hash_type_index.pass.cpp | 2 + .../nothing_to_do.pass.cpp | 13 - .../as_const/as_const.compile.fail.cpp | 23 + .../utility/as_const/as_const.fail.cpp | 23 - .../utility/as_const/as_const.pass.cpp | 2 +- .../utility/exchange/exchange.pass.cpp | 36 +- .../utility/forward/forward.fail.cpp | 2 +- .../utility/forward/forward.pass.cpp | 2 +- .../utilities/utility/forward/move.fail.cpp | 2 +- .../utilities/utility/forward/move.pass.cpp | 8 +- .../utility/pairs/nothing_to_do.pass.cpp | 13 - ...st.fail.cpp => get_const.compile.fail.cpp} | 0 .../pairs/pair.astuple/get_const_rv.pass.cpp | 2 +- .../pairs/pair.astuple/get_rv.pass.cpp | 2 +- .../pairs/pair.astuple/pairs.by.type.pass.cpp | 2 +- .../pairs.by.type1.compile.fail.cpp | 22 + .../pair.astuple/pairs.by.type1.fail.cpp | 22 - .../pairs.by.type2.compile.fail.cpp | 22 + .../pair.astuple/pairs.by.type2.fail.cpp | 22 - .../pairs.by.type3.compile.fail.cpp | 22 + .../pair.astuple/pairs.by.type3.fail.cpp | 22 - .../pairs/pair.astuple/tuple_element.fail.cpp | 4 +- .../piecewise_construct.pass.cpp | 31 +- .../piecewise_construct_t.fail.cpp | 6 +- .../piecewise_construct_t.pass.cpp | 2 +- .../utility/pairs/pairs.pair/U_V.pass.cpp | 52 +- .../pairs.pair/assign_const_pair_U_V.pass.cpp | 89 +- .../pairs/pairs.pair/assign_pair.pass.cpp | 142 +- .../pairs.pair/assign_pair_cxx03.pass.cpp | 2 +- .../pairs/pairs.pair/assign_rv_pair.pass.cpp | 176 +- .../pairs.pair/assign_rv_pair_U_V.pass.cpp | 151 +- .../const_first_const_second.pass.cpp | 2 +- .../pairs/pairs.pair/const_pair_U_V.pass.cpp | 229 +- .../pairs.pair/ctor.brace-init.P1951.pass.cpp | 48 + .../pairs/pairs.pair/ctor.brace-init.pass.cpp | 122 + .../pairs/pairs.pair/default-sfinae.pass.cpp | 2 +- .../pairs.pair/default.explicit.fail.cpp | 6 +- .../utility/pairs/pairs.pair/dtor.pass.cpp | 2 +- .../implicit_deduction_guides.pass.cpp | 3 +- .../pairs/pairs.pair/move_ctor.pass.cpp | 35 +- .../pairs/pairs.pair/piecewise.pass.cpp | 30 +- .../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 48 +- .../special_member_generation_test.pass.cpp | 2 +- .../utility/pairs/pairs.pair/swap.pass.cpp | 61 +- test/std/utilities/utility/synopsis.pass.cpp | 3 +- .../utility/utility.inplace/inplace.pass.cpp | 3 +- .../intcmp.cmp_equal/cmp_equal.pass.cpp | 107 + .../intcmp.cmp_greater/cmp_greater.pass.cpp | 98 + .../cmp_greater_equal.pass.cpp | 100 + .../intcmp.cmp_less/cmp_less.pass.cpp | 99 + .../cmp_less_equal.pass.cpp | 99 + .../cmp_not_equal.pass.cpp | 106 + .../utility/utility.intcmp/intcmp.fail.cpp | 152 + .../intcmp.in_range/in_range.pass.cpp | 82 + .../utility/utility.swap/swap.pass.cpp | 3 +- .../utility/utility.swap/swap_array.pass.cpp | 4 +- .../utility.underlying/to_underlying.pass.cpp | 85 + .../to_underlying.verify.cpp | 24 + .../bad_variant_access.pass.cpp | 7 +- .../variant.general/nothing_to_do.pass.cpp | 1 - .../variant/variant.get/get_if_index.pass.cpp | 3 +- .../variant/variant.get/get_if_type.pass.cpp | 3 +- .../variant/variant.get/get_index.pass.cpp | 14 +- .../variant/variant.get/get_type.pass.cpp | 14 +- .../variant.get/holds_alternative.pass.cpp | 3 +- .../variant.hash/enabled_hash.pass.cpp | 2 +- .../variant/variant.hash/hash.pass.cpp | 3 +- .../variant_alternative.fail.cpp | 3 +- .../variant_alternative.pass.cpp | 3 +- .../variant.helpers/variant_size.pass.cpp | 3 +- .../variant.monostate.relops/relops.pass.cpp | 3 +- .../variant.monostate/monostate.pass.cpp | 3 +- .../variant/variant.relops/relops.pass.cpp | 3 +- .../variant.relops/relops_bool_conv.fail.cpp | 3 +- .../variant.synopsis/variant_npos.pass.cpp | 3 +- .../variant.variant/variant.assign/T.pass.cpp | 6 +- .../variant.assign/conv.pass.cpp | 3 +- .../variant.assign/copy.fail.cpp | 3 +- .../variant.assign/copy.pass.cpp | 10 +- .../variant.assign/move.pass.cpp | 11 +- .../variant.variant/variant.ctor/T.pass.cpp | 7 +- .../variant.ctor/conv.pass.cpp | 3 +- .../variant.ctor/copy.pass.cpp | 12 +- .../variant.ctor/default.pass.cpp | 6 +- .../variant.ctor/in_place_index_args.pass.cpp | 6 +- .../in_place_index_init_list_args.pass.cpp | 7 +- .../variant.ctor/in_place_type_args.pass.cpp | 6 +- .../in_place_type_init_list_args.pass.cpp | 7 +- .../variant.ctor/move.pass.cpp | 12 +- .../variant.dtor/dtor.pass.cpp | 3 +- .../variant.mod/emplace_index_args.pass.cpp | 6 +- .../emplace_index_init_list_args.pass.cpp | 6 +- .../variant.mod/emplace_type_args.pass.cpp | 6 +- .../emplace_type_init_list_args.pass.cpp | 6 +- .../variant.status/index.pass.cpp | 3 +- .../valueless_by_exception.pass.cpp | 3 +- .../variant.swap/swap.pass.cpp | 6 +- .../variant.variant/variant_array.fail.cpp | 3 +- .../variant.variant/variant_empty.fail.cpp | 3 +- .../variant_reference.fail.cpp | 3 +- .../variant.variant/variant_void.fail.cpp | 3 +- .../variant.visit/robust_against_adl.pass.cpp | 46 + .../variant/variant.visit/visit.pass.cpp | 299 +- .../variant.visit/visit_return_type.pass.cpp | 521 + test/support/DefaultOnly.h | 2 +- test/support/MoveOnly.h | 46 +- test/support/allocators.h | 53 +- test/support/any_helpers.h | 11 +- test/support/archetypes.h | 16 +- test/support/asan_testing.h | 2 +- test/support/assert_checkpoint.h | 73 - test/support/atomic_helpers.h | 142 + test/support/callable_types.h | 186 + test/support/charconv_test_helpers.h | 15 +- test/support/cmpxchg_loop.h | 16 +- test/support/compare_types.h | 531 + test/support/constexpr_char_traits.h | 2 +- test/support/container_debug_tests.h | 37 +- test/support/container_test_types.h | 6 +- test/support/controlled_allocators.h | 19 +- test/support/coroutine_types.h | 74 - test/support/count_new.h | 7 + test/support/debug_macros.h | 33 + test/support/debug_mode_helper.h | 45 +- test/support/deduction_guides_sfinae_checks.h | 309 + test/support/deleter_types.h | 22 +- test/support/demangle.h | 46 - test/support/disable_missing_braces_warning.h | 19 - test/support/emplace_constructible.h | 20 +- test/support/experimental_any_helpers.h | 6 - .../support/filesystem_dynamic_test_helper.py | 92 - test/support/filesystem_test_helper.h | 643 +- test/support/indirectly_readable.h | 38 + test/support/is_transparent.h | 6 +- .../support/iterator_traits_cpp17_iterators.h | 104 + test/support/make_implicit.h | 22 + test/support/make_string.h | 102 + test/support/make_test_thread.h | 23 + test/support/min_allocator.h | 176 +- test/support/msvc_stdlib_force_include.h | 26 +- test/support/nasty_containers.h | 8 +- test/support/nasty_macros.h | 68 - test/support/nothing_to_do.pass.cpp | 15 - test/support/operator_hijacker.h | 39 + test/support/parse_integer.h | 72 + test/support/platform_support.h | 82 +- test/support/pointer_comparison_test_helper.h | 61 + test/support/poisoned_hash_helper.h | 73 +- test/support/private_constructor.h | 10 +- test/support/propagate_const_helpers.h | 1 - test/support/propagate_value_category.hpp | 153 + test/support/read_write.h | 36 + .../test.support/make_string_header.pass.cpp | 56 + .../test_convertible_header.pass.cpp | 2 +- .../test.support/test_demangle.pass.cpp | 40 - .../test_macros_header.exceptions.pass.cpp | 23 + ...est_macros_header.no_exceptions.verify.cpp | 23 + .../test_macros_header.no_rtti.verify.cpp | 27 + .../test_macros_header.rtti.pass.cpp | 28 + .../test_macros_header_exceptions.fail.cpp | 25 - .../test_macros_header_exceptions.pass.cpp | 25 - .../test_macros_header_rtti.fail.cpp | 30 - .../test_macros_header_rtti.pass.cpp | 30 - .../test_poisoned_hash_helper.pass.cpp | 2 +- ...c1xx_broken_is_trivially_copyable.pass.cpp | 6 +- .../c1xx_broken_za_ctor_check.pass.cpp | 6 +- test/support/test_allocator.h | 695 +- test/support/test_basic_format_arg.h | 24 + test/support/test_comparisons.h | 15 + test/support/test_constexpr_container.h | 56 + test/support/test_format_context.h | 62 + test/support/test_iterators.h | 791 +- test/support/test_macros.h | 204 +- test/support/test_range.h | 82 + test/support/test_transparent_unordered.h | 187 + test/support/test_workarounds.h | 14 +- test/support/tracked_value.h | 59 - test/support/type_classification/copyable.h | 77 + test/support/type_classification/movable.h | 162 + .../type_classification/moveconstructible.h | 74 + .../support/type_classification/semiregular.h | 29 + test/support/type_classification/swappable.h | 266 + test/support/type_id.h | 33 +- test/support/unique_ptr_test_helper.h | 2 +- test/support/user_defined_integral.h | 8 +- test/support/uses_alloc_types.h | 43 +- test/support/variant_test_helpers.h | 79 + test/support/verbose_assert.h | 222 - utils/CMakeLists.txt | 23 + utils/ci/Dockerfile | 102 + utils/ci/apple-install-libcxx.sh | 176 + utils/ci/buildkite-pipeline-premerge.sh | 40 + utils/ci/buildkite-pipeline-snapshot.sh | 25 + utils/ci/buildkite-pipeline.yml | 743 ++ utils/ci/macos-backdeployment.sh | 145 - utils/ci/macos-ci-setup | 100 + utils/ci/macos-trunk.sh | 132 - utils/ci/oss-fuzz.sh | 33 + utils/ci/run-buildbot | 670 + utils/ci/run-buildbot-container | 30 + utils/docker/debian9/Dockerfile.base | 46 - utils/docker/debian9/Dockerfile.buildbot | 26 - utils/docker/debian9/Dockerfile.clang | 19 - utils/docker/debian9/Dockerfile.compiler_zoo | 35 - utils/docker/debian9/Dockerfile.gcc | 18 - utils/docker/docker-compose.yml | 46 - utils/docker/scripts/build_gcc_version.sh | 108 - utils/docker/scripts/build_llvm_version.sh | 106 - .../docker/scripts/docker_start_buildbots.sh | 8 - utils/docker/scripts/docker_update_bot.sh | 25 - .../docker/scripts/install_clang_packages.sh | 81 - utils/docker/scripts/run_buildbot.sh | 103 - utils/gdb/libcxx/printers.py | 93 +- utils/generate_abi_list.py | 40 + .../generate_feature_test_macro_components.py | 1438 +- utils/generate_header_inclusion_tests.py | 205 + utils/generate_header_tests.py | 212 + utils/generate_private_header_tests.py | 80 + utils/google-benchmark/.clang-format | 5 - utils/google-benchmark/.gitignore | 58 - .../google-benchmark/.travis-libcxx-setup.sh | 28 - utils/google-benchmark/.travis.yml | 199 - utils/google-benchmark/.ycm_extra_conf.py | 115 - utils/google-benchmark/AUTHORS | 48 - utils/google-benchmark/CMakeLists.txt | 267 - utils/google-benchmark/CONTRIBUTING.md | 58 - utils/google-benchmark/CONTRIBUTORS | 68 - utils/google-benchmark/LICENSE | 202 - utils/google-benchmark/README.LLVM | 16 - utils/google-benchmark/README.md | 998 -- utils/google-benchmark/WORKSPACE | 7 - utils/google-benchmark/appveyor.yml | 50 - .../cmake/AddCXXCompilerFlag.cmake | 74 - .../cmake/CXXFeatureCheck.cmake | 64 - utils/google-benchmark/cmake/Config.cmake.in | 1 - .../cmake/GetGitVersion.cmake | 54 - .../google-benchmark/cmake/HandleGTest.cmake | 113 - utils/google-benchmark/cmake/benchmark.pc.in | 11 - .../cmake/gnu_posix_regex.cpp | 12 - .../cmake/llvm-toolchain.cmake | 8 - utils/google-benchmark/cmake/posix_regex.cpp | 14 - utils/google-benchmark/cmake/split_list.cmake | 3 - utils/google-benchmark/cmake/std_regex.cpp | 10 - utils/google-benchmark/cmake/steady_clock.cpp | 7 - .../cmake/thread_safety_attributes.cpp | 4 - utils/google-benchmark/docs/AssemblyTests.md | 147 - utils/google-benchmark/docs/tools.md | 199 - .../include/benchmark/benchmark.h | 1551 --- utils/google-benchmark/mingw.py | 320 - utils/google-benchmark/releasing.md | 16 - utils/google-benchmark/src/CMakeLists.txt | 108 - utils/google-benchmark/src/arraysize.h | 33 - utils/google-benchmark/src/benchmark.cc | 493 - .../src/benchmark_api_internal.cc | 15 - .../src/benchmark_api_internal.h | 52 - utils/google-benchmark/src/benchmark_main.cc | 17 - .../src/benchmark_register.cc | 482 - .../google-benchmark/src/benchmark_register.h | 33 - .../google-benchmark/src/benchmark_runner.cc | 350 - utils/google-benchmark/src/benchmark_runner.h | 51 - utils/google-benchmark/src/check.h | 82 - utils/google-benchmark/src/colorprint.cc | 188 - utils/google-benchmark/src/colorprint.h | 33 - .../google-benchmark/src/commandlineflags.cc | 218 - utils/google-benchmark/src/commandlineflags.h | 79 - utils/google-benchmark/src/complexity.cc | 228 - utils/google-benchmark/src/complexity.h | 55 - .../google-benchmark/src/console_reporter.cc | 180 - utils/google-benchmark/src/counter.cc | 75 - utils/google-benchmark/src/counter.h | 26 - utils/google-benchmark/src/csv_reporter.cc | 153 - utils/google-benchmark/src/cycleclock.h | 192 - utils/google-benchmark/src/internal_macros.h | 92 - utils/google-benchmark/src/json_reporter.cc | 220 - utils/google-benchmark/src/log.h | 74 - utils/google-benchmark/src/mutex.h | 155 - utils/google-benchmark/src/re.h | 158 - utils/google-benchmark/src/reporter.cc | 105 - utils/google-benchmark/src/sleep.cc | 51 - utils/google-benchmark/src/sleep.h | 15 - utils/google-benchmark/src/statistics.cc | 190 - utils/google-benchmark/src/statistics.h | 37 - utils/google-benchmark/src/string_util.cc | 261 - utils/google-benchmark/src/string_util.h | 60 - utils/google-benchmark/src/sysinfo.cc | 650 - utils/google-benchmark/src/thread_manager.h | 64 - utils/google-benchmark/src/thread_timer.h | 69 - utils/google-benchmark/src/timers.cc | 217 - utils/google-benchmark/src/timers.h | 48 - .../google-benchmark/test/AssemblyTests.cmake | 46 - utils/google-benchmark/test/CMakeLists.txt | 260 - utils/google-benchmark/test/basic_test.cc | 136 - .../google-benchmark/test/benchmark_gtest.cc | 33 - utils/google-benchmark/test/benchmark_test.cc | 245 - .../test/clobber_memory_assembly_test.cc | 64 - .../google-benchmark/test/complexity_test.cc | 183 - utils/google-benchmark/test/cxx03_test.cc | 63 - .../google-benchmark/test/diagnostics_test.cc | 80 - .../test/display_aggregates_only_test.cc | 43 - .../test/donotoptimize_assembly_test.cc | 163 - .../test/donotoptimize_test.cc | 52 - utils/google-benchmark/test/filter_test.cc | 104 - utils/google-benchmark/test/fixture_test.cc | 49 - utils/google-benchmark/test/link_main_test.cc | 8 - utils/google-benchmark/test/map_test.cc | 57 - .../test/memory_manager_test.cc | 42 - .../test/multiple_ranges_test.cc | 97 - utils/google-benchmark/test/options_test.cc | 65 - utils/google-benchmark/test/output_test.h | 213 - .../test/output_test_helper.cc | 505 - .../test/register_benchmark_test.cc | 184 - .../test/report_aggregates_only_test.cc | 39 - .../test/reporter_output_test.cc | 604 - .../test/skip_with_error_test.cc | 189 - .../test/state_assembly_test.cc | 68 - .../google-benchmark/test/statistics_gtest.cc | 28 - .../test/string_util_gtest.cc | 146 - .../test/templated_fixture_test.cc | 28 - .../test/user_counters_tabular_test.cc | 268 - .../test/user_counters_test.cc | 408 - .../test/user_counters_thousands_test.cc | 161 - utils/google-benchmark/tools/compare.py | 408 - .../tools/gbench/Inputs/test1_run1.json | 102 - .../tools/gbench/Inputs/test1_run2.json | 102 - .../tools/gbench/Inputs/test2_run.json | 81 - .../tools/gbench/Inputs/test3_run0.json | 65 - .../tools/gbench/Inputs/test3_run1.json | 65 - .../google-benchmark/tools/gbench/__init__.py | 8 - utils/google-benchmark/tools/gbench/report.py | 522 - utils/google-benchmark/tools/gbench/util.py | 164 - utils/google-benchmark/tools/strip_asm.py | 151 - utils/graph_header_deps.py | 224 + utils/libcxx/sym_check/util.py | 14 +- utils/libcxx/test/config.py | 942 +- utils/libcxx/test/dsl.py | 690 + utils/libcxx/test/executor.py | 197 - utils/libcxx/test/features.py | 220 + utils/libcxx/test/format.py | 494 +- utils/libcxx/test/googlebenchmark.py | 1 - utils/libcxx/test/newconfig.py | 38 + utils/libcxx/test/params.py | 220 + utils/libcxx/test/target_info.py | 194 +- utils/libcxx/test/tracing.py | 42 - utils/libcxx/util.py | 28 +- utils/merge_archives.py | 4 +- utils/not.py | 51 - utils/run.py | 47 +- utils/ssh.py | 125 + utils/sym_extract.py | 54 - utils/sym_match.py | 50 - www/atomic_design.html | 91 - www/atomic_design_a.html | 308 - www/atomic_design_b.html | 249 - www/atomic_design_c.html | 457 - www/content.css | 27 - www/cxx1y_status.html | 277 - www/cxx1z_status.html | 509 - www/cxx2a_status.html | 385 - www/index.html | 228 - www/menu.css | 39 - www/ts1z_status.html | 108 - www/type_traits_design.html | 285 - www/upcoming_meeting.html | 118 - 7218 files changed, 322220 insertions(+), 149030 deletions(-) delete mode 100644 NOTES.TXT create mode 100644 benchmarks/VariantBenchmarks.h create mode 100644 benchmarks/format.bench.cpp create mode 100644 benchmarks/format_to.bench.cpp create mode 100644 benchmarks/format_to_n.bench.cpp create mode 100644 benchmarks/formatted_size.bench.cpp create mode 100644 benchmarks/formatter_float.bench.cpp create mode 100644 benchmarks/map.bench.cpp create mode 100644 benchmarks/std_format_spec_string_unicode.bench.cpp create mode 100644 benchmarks/to_chars.bench.cpp create mode 100644 benchmarks/variant_visit_1.bench.cpp create mode 100644 benchmarks/variant_visit_2.bench.cpp create mode 100644 benchmarks/variant_visit_3.bench.cpp delete mode 100644 cmake/Modules/CheckLibcxxAtomic.cmake delete mode 100644 cmake/Modules/HandleCompilerRT.cmake delete mode 100644 cmake/Modules/HandleOutOfTreeLLVM.cmake create mode 100644 cmake/caches/AArch64.cmake create mode 100644 cmake/caches/AIX.cmake create mode 100644 cmake/caches/Armv7Arm.cmake create mode 100644 cmake/caches/Armv7Thumb-noexceptions.cmake create mode 100644 cmake/caches/Armv8Arm.cmake create mode 100644 cmake/caches/Armv8Thumb-noexceptions.cmake create mode 100644 cmake/caches/FreeBSD.cmake create mode 100644 cmake/caches/Generic-asan.cmake create mode 100644 cmake/caches/Generic-assertions.cmake create mode 100644 cmake/caches/Generic-cxx03.cmake create mode 100644 cmake/caches/Generic-cxx11.cmake create mode 100644 cmake/caches/Generic-cxx14.cmake create mode 100644 cmake/caches/Generic-cxx17.cmake create mode 100644 cmake/caches/Generic-cxx20.cmake create mode 100644 cmake/caches/Generic-cxx2b.cmake create mode 100644 cmake/caches/Generic-debug-iterators.cmake create mode 100644 cmake/caches/Generic-modules.cmake create mode 100644 cmake/caches/Generic-msan.cmake create mode 100644 cmake/caches/Generic-no-debug.cmake create mode 100644 cmake/caches/Generic-no-experimental.cmake create mode 100644 cmake/caches/Generic-no-filesystem.cmake create mode 100644 cmake/caches/Generic-no-localization.cmake create mode 100644 cmake/caches/Generic-no-random_device.cmake create mode 100644 cmake/caches/Generic-no-unicode.cmake create mode 100644 cmake/caches/Generic-no-wide-characters.cmake create mode 100644 cmake/caches/Generic-noexceptions.cmake create mode 100644 cmake/caches/Generic-singlethreaded.cmake create mode 100644 cmake/caches/Generic-static.cmake create mode 100644 cmake/caches/Generic-tsan.cmake create mode 100644 cmake/caches/Generic-ubsan.cmake create mode 100644 cmake/caches/MinGW.cmake create mode 100644 cmake/caches/README.md create mode 100644 docs/AddingNewCIJobs.rst create mode 100644 docs/Contributing.rst create mode 100644 docs/DesignDocs/AtomicDesign.rst delete mode 100644 docs/DesignDocs/AvailabilityMarkup.rst create mode 100644 docs/DesignDocs/NoexceptPolicy.rst create mode 100644 docs/DesignDocs/UniquePtrTrivialAbi.rst create mode 100644 docs/DesignDocs/UnspecifiedBehaviorRandomization.rst create mode 100644 docs/Helpers/Styles.rst delete mode 100644 docs/Makefile.sphinx create mode 100644 docs/Status/Cxx14.rst create mode 100644 docs/Status/Cxx14Issues.csv create mode 100644 docs/Status/Cxx14Papers.csv create mode 100644 docs/Status/Cxx17.rst create mode 100644 docs/Status/Cxx17Issues.csv create mode 100644 docs/Status/Cxx17Papers.csv create mode 100644 docs/Status/Cxx20.rst create mode 100644 docs/Status/Cxx20Issues.csv create mode 100644 docs/Status/Cxx20Papers.csv create mode 100644 docs/Status/Cxx2b.rst create mode 100644 docs/Status/Cxx2bIssues.csv create mode 100644 docs/Status/Cxx2bPapers.csv create mode 100644 docs/Status/Format.rst create mode 100644 docs/Status/FormatIssues.csv create mode 100644 docs/Status/FormatPaper.csv create mode 100644 docs/Status/Ranges.rst create mode 100644 docs/Status/RangesAlgorithms.csv create mode 100644 docs/Status/RangesIssues.csv create mode 100644 docs/Status/RangesPaper.csv create mode 100644 docs/Status/Spaceship.rst create mode 100644 docs/Status/SpaceshipPapers.csv create mode 100644 docs/Status/SpaceshipProjects.csv create mode 100644 docs/Status/Zip.rst create mode 100644 docs/Status/ZipProjects.csv delete mode 100644 fuzzing/RoutineNames.txt delete mode 100644 fuzzing/fuzz_test.cpp delete mode 100644 fuzzing/fuzzing.cpp delete mode 100644 fuzzing/fuzzing.h create mode 100644 include/__algorithm/adjacent_find.h create mode 100644 include/__algorithm/all_of.h create mode 100644 include/__algorithm/any_of.h create mode 100644 include/__algorithm/binary_search.h create mode 100644 include/__algorithm/clamp.h create mode 100644 include/__algorithm/comp.h create mode 100644 include/__algorithm/comp_ref_type.h create mode 100644 include/__algorithm/copy.h create mode 100644 include/__algorithm/copy_backward.h create mode 100644 include/__algorithm/copy_if.h create mode 100644 include/__algorithm/copy_n.h create mode 100644 include/__algorithm/count.h create mode 100644 include/__algorithm/count_if.h create mode 100644 include/__algorithm/equal.h create mode 100644 include/__algorithm/equal_range.h create mode 100644 include/__algorithm/fill.h create mode 100644 include/__algorithm/fill_n.h create mode 100644 include/__algorithm/find.h create mode 100644 include/__algorithm/find_end.h create mode 100644 include/__algorithm/find_first_of.h create mode 100644 include/__algorithm/find_if.h create mode 100644 include/__algorithm/find_if_not.h create mode 100644 include/__algorithm/for_each.h create mode 100644 include/__algorithm/for_each_n.h create mode 100644 include/__algorithm/generate.h create mode 100644 include/__algorithm/generate_n.h create mode 100644 include/__algorithm/half_positive.h create mode 100644 include/__algorithm/in_in_out_result.h create mode 100644 include/__algorithm/in_in_result.h create mode 100644 include/__algorithm/in_out_result.h create mode 100644 include/__algorithm/includes.h create mode 100644 include/__algorithm/inplace_merge.h create mode 100644 include/__algorithm/is_heap.h create mode 100644 include/__algorithm/is_heap_until.h create mode 100644 include/__algorithm/is_partitioned.h create mode 100644 include/__algorithm/is_permutation.h create mode 100644 include/__algorithm/is_sorted.h create mode 100644 include/__algorithm/is_sorted_until.h create mode 100644 include/__algorithm/iter_swap.h create mode 100644 include/__algorithm/lexicographical_compare.h create mode 100644 include/__algorithm/lower_bound.h create mode 100644 include/__algorithm/make_heap.h create mode 100644 include/__algorithm/max.h create mode 100644 include/__algorithm/max_element.h create mode 100644 include/__algorithm/merge.h create mode 100644 include/__algorithm/min.h create mode 100644 include/__algorithm/min_element.h create mode 100644 include/__algorithm/minmax.h create mode 100644 include/__algorithm/minmax_element.h create mode 100644 include/__algorithm/mismatch.h create mode 100644 include/__algorithm/move.h create mode 100644 include/__algorithm/move_backward.h create mode 100644 include/__algorithm/next_permutation.h create mode 100644 include/__algorithm/none_of.h create mode 100644 include/__algorithm/nth_element.h create mode 100644 include/__algorithm/partial_sort.h create mode 100644 include/__algorithm/partial_sort_copy.h create mode 100644 include/__algorithm/partition.h create mode 100644 include/__algorithm/partition_copy.h create mode 100644 include/__algorithm/partition_point.h create mode 100644 include/__algorithm/pop_heap.h create mode 100644 include/__algorithm/prev_permutation.h create mode 100644 include/__algorithm/push_heap.h create mode 100644 include/__algorithm/remove.h create mode 100644 include/__algorithm/remove_copy.h create mode 100644 include/__algorithm/remove_copy_if.h create mode 100644 include/__algorithm/remove_if.h create mode 100644 include/__algorithm/replace.h create mode 100644 include/__algorithm/replace_copy.h create mode 100644 include/__algorithm/replace_copy_if.h create mode 100644 include/__algorithm/replace_if.h create mode 100644 include/__algorithm/reverse.h create mode 100644 include/__algorithm/reverse_copy.h create mode 100644 include/__algorithm/rotate.h create mode 100644 include/__algorithm/rotate_copy.h create mode 100644 include/__algorithm/sample.h create mode 100644 include/__algorithm/search.h create mode 100644 include/__algorithm/search_n.h create mode 100644 include/__algorithm/set_difference.h create mode 100644 include/__algorithm/set_intersection.h create mode 100644 include/__algorithm/set_symmetric_difference.h create mode 100644 include/__algorithm/set_union.h create mode 100644 include/__algorithm/shift_left.h create mode 100644 include/__algorithm/shift_right.h create mode 100644 include/__algorithm/shuffle.h create mode 100644 include/__algorithm/sift_down.h create mode 100644 include/__algorithm/sort.h create mode 100644 include/__algorithm/sort_heap.h create mode 100644 include/__algorithm/stable_partition.h create mode 100644 include/__algorithm/stable_sort.h create mode 100644 include/__algorithm/swap_ranges.h create mode 100644 include/__algorithm/transform.h create mode 100644 include/__algorithm/unique.h create mode 100644 include/__algorithm/unique_copy.h create mode 100644 include/__algorithm/unwrap_iter.h create mode 100644 include/__algorithm/upper_bound.h create mode 100644 include/__availability create mode 100644 include/__bit/bit_cast.h create mode 100644 include/__bit/byteswap.h create mode 100644 include/__bits create mode 100644 include/__charconv/chars_format.h create mode 100644 include/__charconv/from_chars_result.h create mode 100644 include/__charconv/to_chars_result.h create mode 100644 include/__chrono/calendar.h create mode 100644 include/__chrono/convert_to_timespec.h create mode 100644 include/__chrono/duration.h create mode 100644 include/__chrono/file_clock.h create mode 100644 include/__chrono/high_resolution_clock.h create mode 100644 include/__chrono/steady_clock.h create mode 100644 include/__chrono/system_clock.h create mode 100644 include/__chrono/time_point.h create mode 100644 include/__compare/common_comparison_category.h create mode 100644 include/__compare/compare_partial_order_fallback.h create mode 100644 include/__compare/compare_strong_order_fallback.h create mode 100644 include/__compare/compare_three_way.h create mode 100644 include/__compare/compare_three_way_result.h create mode 100644 include/__compare/compare_weak_order_fallback.h create mode 100644 include/__compare/is_eq.h create mode 100644 include/__compare/ordering.h create mode 100644 include/__compare/partial_order.h create mode 100644 include/__compare/strong_order.h create mode 100644 include/__compare/synth_three_way.h create mode 100644 include/__compare/three_way_comparable.h create mode 100644 include/__compare/weak_order.h create mode 100644 include/__concepts/arithmetic.h create mode 100644 include/__concepts/assignable.h create mode 100644 include/__concepts/boolean_testable.h create mode 100644 include/__concepts/class_or_enum.h create mode 100644 include/__concepts/common_reference_with.h create mode 100644 include/__concepts/common_with.h create mode 100644 include/__concepts/constructible.h create mode 100644 include/__concepts/convertible_to.h create mode 100644 include/__concepts/copyable.h create mode 100644 include/__concepts/derived_from.h create mode 100644 include/__concepts/destructible.h create mode 100644 include/__concepts/different_from.h create mode 100644 include/__concepts/equality_comparable.h create mode 100644 include/__concepts/invocable.h create mode 100644 include/__concepts/movable.h create mode 100644 include/__concepts/predicate.h create mode 100644 include/__concepts/regular.h create mode 100644 include/__concepts/relation.h create mode 100644 include/__concepts/same_as.h create mode 100644 include/__concepts/semiregular.h create mode 100644 include/__concepts/swappable.h create mode 100644 include/__concepts/totally_ordered.h create mode 100644 include/__coroutine/coroutine_handle.h create mode 100644 include/__coroutine/coroutine_traits.h create mode 100644 include/__coroutine/noop_coroutine_handle.h create mode 100644 include/__coroutine/trivial_awaitables.h create mode 100644 include/__filesystem/copy_options.h create mode 100644 include/__filesystem/directory_entry.h create mode 100644 include/__filesystem/directory_iterator.h create mode 100644 include/__filesystem/directory_options.h create mode 100644 include/__filesystem/file_status.h create mode 100644 include/__filesystem/file_time_type.h create mode 100644 include/__filesystem/file_type.h create mode 100644 include/__filesystem/filesystem_error.h create mode 100644 include/__filesystem/operations.h create mode 100644 include/__filesystem/path.h create mode 100644 include/__filesystem/path_iterator.h create mode 100644 include/__filesystem/perm_options.h create mode 100644 include/__filesystem/perms.h create mode 100644 include/__filesystem/recursive_directory_iterator.h create mode 100644 include/__filesystem/space_info.h create mode 100644 include/__filesystem/u8path.h create mode 100644 include/__format/format_arg.h create mode 100644 include/__format/format_args.h create mode 100644 include/__format/format_context.h create mode 100644 include/__format/format_error.h create mode 100644 include/__format/format_fwd.h create mode 100644 include/__format/format_parse_context.h create mode 100644 include/__format/format_string.h create mode 100644 include/__format/format_to_n_result.h create mode 100644 include/__format/formatter.h create mode 100644 include/__format/formatter_bool.h create mode 100644 include/__format/formatter_char.h create mode 100644 include/__format/formatter_floating_point.h create mode 100644 include/__format/formatter_integer.h create mode 100644 include/__format/formatter_integral.h create mode 100644 include/__format/formatter_pointer.h create mode 100644 include/__format/formatter_string.h create mode 100644 include/__format/parser_std_format_spec.h create mode 100644 include/__functional/binary_function.h create mode 100644 include/__functional/binary_negate.h create mode 100644 include/__functional/bind.h create mode 100644 include/__functional/bind_back.h create mode 100644 include/__functional/bind_front.h create mode 100644 include/__functional/binder1st.h create mode 100644 include/__functional/binder2nd.h create mode 100644 include/__functional/compose.h create mode 100644 include/__functional/default_searcher.h create mode 100644 include/__functional/function.h create mode 100644 include/__functional/hash.h create mode 100644 include/__functional/identity.h create mode 100644 include/__functional/invoke.h create mode 100644 include/__functional/is_transparent.h create mode 100644 include/__functional/mem_fn.h create mode 100644 include/__functional/mem_fun_ref.h create mode 100644 include/__functional/not_fn.h create mode 100644 include/__functional/operations.h create mode 100644 include/__functional/perfect_forward.h create mode 100644 include/__functional/pointer_to_binary_function.h create mode 100644 include/__functional/pointer_to_unary_function.h create mode 100644 include/__functional/ranges_operations.h create mode 100644 include/__functional/reference_wrapper.h create mode 100644 include/__functional/unary_function.h create mode 100644 include/__functional/unary_negate.h create mode 100644 include/__functional/unwrap_ref.h create mode 100644 include/__functional/weak_result_type.h delete mode 100644 include/__functional_03 delete mode 100644 include/__functional_base_03 create mode 100644 include/__iterator/access.h create mode 100644 include/__iterator/advance.h create mode 100644 include/__iterator/back_insert_iterator.h create mode 100644 include/__iterator/common_iterator.h create mode 100644 include/__iterator/concepts.h create mode 100644 include/__iterator/counted_iterator.h create mode 100644 include/__iterator/data.h create mode 100644 include/__iterator/default_sentinel.h create mode 100644 include/__iterator/distance.h create mode 100644 include/__iterator/empty.h create mode 100644 include/__iterator/erase_if_container.h create mode 100644 include/__iterator/front_insert_iterator.h create mode 100644 include/__iterator/incrementable_traits.h create mode 100644 include/__iterator/indirectly_comparable.h create mode 100644 include/__iterator/insert_iterator.h create mode 100644 include/__iterator/istream_iterator.h create mode 100644 include/__iterator/istreambuf_iterator.h create mode 100644 include/__iterator/iter_move.h create mode 100644 include/__iterator/iter_swap.h create mode 100644 include/__iterator/iterator.h create mode 100644 include/__iterator/iterator_traits.h create mode 100644 include/__iterator/move_iterator.h create mode 100644 include/__iterator/next.h create mode 100644 include/__iterator/ostream_iterator.h create mode 100644 include/__iterator/ostreambuf_iterator.h create mode 100644 include/__iterator/prev.h create mode 100644 include/__iterator/projected.h create mode 100644 include/__iterator/readable_traits.h create mode 100644 include/__iterator/reverse_access.h create mode 100644 include/__iterator/reverse_iterator.h create mode 100644 include/__iterator/size.h create mode 100644 include/__iterator/unreachable_sentinel.h create mode 100644 include/__iterator/wrap_iter.h create mode 100644 include/__mbstate_t.h create mode 100644 include/__memory/addressof.h create mode 100644 include/__memory/allocation_guard.h create mode 100644 include/__memory/allocator.h create mode 100644 include/__memory/allocator_arg_t.h create mode 100644 include/__memory/allocator_traits.h create mode 100644 include/__memory/auto_ptr.h create mode 100644 include/__memory/compressed_pair.h create mode 100644 include/__memory/concepts.h create mode 100644 include/__memory/construct_at.h create mode 100644 include/__memory/pointer_traits.h create mode 100644 include/__memory/ranges_construct_at.h create mode 100644 include/__memory/ranges_uninitialized_algorithms.h create mode 100644 include/__memory/raw_storage_iterator.h create mode 100644 include/__memory/shared_ptr.h create mode 100644 include/__memory/temporary_buffer.h create mode 100644 include/__memory/uninitialized_algorithms.h create mode 100644 include/__memory/unique_ptr.h create mode 100644 include/__memory/uses_allocator.h create mode 100644 include/__memory/voidify.h create mode 100644 include/__numeric/accumulate.h create mode 100644 include/__numeric/adjacent_difference.h create mode 100644 include/__numeric/exclusive_scan.h create mode 100644 include/__numeric/gcd_lcm.h create mode 100644 include/__numeric/inclusive_scan.h create mode 100644 include/__numeric/inner_product.h create mode 100644 include/__numeric/iota.h create mode 100644 include/__numeric/midpoint.h create mode 100644 include/__numeric/partial_sum.h create mode 100644 include/__numeric/reduce.h create mode 100644 include/__numeric/transform_exclusive_scan.h create mode 100644 include/__numeric/transform_inclusive_scan.h create mode 100644 include/__numeric/transform_reduce.h create mode 100644 include/__random/bernoulli_distribution.h create mode 100644 include/__random/binomial_distribution.h create mode 100644 include/__random/cauchy_distribution.h create mode 100644 include/__random/chi_squared_distribution.h create mode 100644 include/__random/clamp_to_integral.h create mode 100644 include/__random/default_random_engine.h create mode 100644 include/__random/discard_block_engine.h create mode 100644 include/__random/discrete_distribution.h create mode 100644 include/__random/exponential_distribution.h create mode 100644 include/__random/extreme_value_distribution.h create mode 100644 include/__random/fisher_f_distribution.h create mode 100644 include/__random/gamma_distribution.h create mode 100644 include/__random/generate_canonical.h create mode 100644 include/__random/geometric_distribution.h create mode 100644 include/__random/independent_bits_engine.h create mode 100644 include/__random/is_seed_sequence.h create mode 100644 include/__random/knuth_b.h create mode 100644 include/__random/linear_congruential_engine.h create mode 100644 include/__random/log2.h create mode 100644 include/__random/lognormal_distribution.h create mode 100644 include/__random/mersenne_twister_engine.h create mode 100644 include/__random/negative_binomial_distribution.h create mode 100644 include/__random/normal_distribution.h create mode 100644 include/__random/piecewise_constant_distribution.h create mode 100644 include/__random/piecewise_linear_distribution.h create mode 100644 include/__random/poisson_distribution.h create mode 100644 include/__random/random_device.h create mode 100644 include/__random/ranlux.h create mode 100644 include/__random/seed_seq.h create mode 100644 include/__random/shuffle_order_engine.h create mode 100644 include/__random/student_t_distribution.h create mode 100644 include/__random/subtract_with_carry_engine.h create mode 100644 include/__random/uniform_int_distribution.h create mode 100644 include/__random/uniform_random_bit_generator.h create mode 100644 include/__random/uniform_real_distribution.h create mode 100644 include/__random/weibull_distribution.h create mode 100644 include/__ranges/access.h create mode 100644 include/__ranges/all.h create mode 100644 include/__ranges/common_view.h create mode 100644 include/__ranges/concepts.h create mode 100644 include/__ranges/copyable_box.h create mode 100644 include/__ranges/counted.h create mode 100644 include/__ranges/dangling.h create mode 100644 include/__ranges/data.h create mode 100644 include/__ranges/drop_view.h create mode 100644 include/__ranges/empty.h create mode 100644 include/__ranges/empty_view.h create mode 100644 include/__ranges/enable_borrowed_range.h create mode 100644 include/__ranges/enable_view.h create mode 100644 include/__ranges/iota_view.h create mode 100644 include/__ranges/join_view.h create mode 100644 include/__ranges/non_propagating_cache.h create mode 100644 include/__ranges/owning_view.h create mode 100644 include/__ranges/range_adaptor.h create mode 100644 include/__ranges/ref_view.h create mode 100644 include/__ranges/reverse_view.h create mode 100644 include/__ranges/single_view.h create mode 100644 include/__ranges/size.h create mode 100644 include/__ranges/subrange.h create mode 100644 include/__ranges/take_view.h create mode 100644 include/__ranges/transform_view.h create mode 100644 include/__ranges/view_interface.h create mode 100644 include/__ranges/views.h delete mode 100644 include/__sso_allocator rename include/{support => __support}/android/locale_bionic.h (88%) create mode 100644 include/__support/fuchsia/xlocale.h create mode 100644 include/__support/ibm/gettod_zos.h rename include/{support => __support}/ibm/limits.h (97%) create mode 100644 include/__support/ibm/locale_mgmt_zos.h create mode 100644 include/__support/ibm/nanosleep.h rename include/{support => __support}/ibm/support.h (95%) create mode 100644 include/__support/ibm/xlocale.h create mode 100644 include/__support/musl/xlocale.h create mode 100644 include/__support/newlib/xlocale.h create mode 100644 include/__support/openbsd/xlocale.h rename include/{support => __support}/solaris/floatingpoint.h (100%) rename include/{support => __support}/solaris/wchar.h (98%) rename include/{support => __support}/solaris/xlocale.h (100%) rename include/{support => __support}/win32/limits_msvc_win32.h (96%) create mode 100644 include/__support/win32/locale_win32.h rename include/{support => __support}/xlocale/__nop_locale_mgmt.h (94%) rename include/{support => __support}/xlocale/__posix_l_fallback.h (98%) rename include/{support => __support}/xlocale/__strtonum_fallback.h (96%) create mode 100644 include/__thread/poll_with_backoff.h create mode 100644 include/__thread/timed_backoff_policy.h create mode 100644 include/__utility/as_const.h create mode 100644 include/__utility/auto_cast.h create mode 100644 include/__utility/cmp.h create mode 100644 include/__utility/declval.h create mode 100644 include/__utility/exchange.h create mode 100644 include/__utility/forward.h create mode 100644 include/__utility/in_place.h create mode 100644 include/__utility/integer_sequence.h create mode 100644 include/__utility/move.h create mode 100644 include/__utility/pair.h create mode 100644 include/__utility/piecewise_construct.h create mode 100644 include/__utility/priority_tag.h create mode 100644 include/__utility/rel_ops.h create mode 100644 include/__utility/swap.h create mode 100644 include/__utility/to_underlying.h create mode 100644 include/__utility/transaction.h create mode 100644 include/__variant/monostate.h create mode 100644 include/barrier create mode 100644 include/concepts create mode 100644 include/coroutine create mode 100644 include/format create mode 100644 include/latch create mode 100644 include/numbers create mode 100644 include/ranges create mode 100644 include/semaphore delete mode 100644 include/support/fuchsia/xlocale.h delete mode 100644 include/support/ibm/locale_mgmt_aix.h delete mode 100644 include/support/ibm/xlocale.h delete mode 100644 include/support/musl/xlocale.h delete mode 100644 include/support/newlib/xlocale.h delete mode 100644 include/support/win32/locale_win32.h delete mode 100644 lib/abi/3.9/x86_64-apple-darwin16.abilist delete mode 100644 lib/abi/3.9/x86_64-linux-gnu.abilist delete mode 100644 lib/abi/4.0/x86_64-apple-darwin16.abilist delete mode 100644 lib/abi/4.0/x86_64-unknown-linux-gnu.abilist delete mode 100644 lib/abi/5.0/x86_64-apple-darwin16.abilist delete mode 100644 lib/abi/5.0/x86_64-unknown-linux-gnu.abilist delete mode 100644 lib/abi/6.0/x86_64-apple-darwin16.abilist delete mode 100644 lib/abi/6.0/x86_64-unknown-linux-gnu.abilist delete mode 100644 lib/abi/8.0/x86_64-apple-darwin.v1.abilist delete mode 100644 lib/abi/8.0/x86_64-apple-darwin.v2.abilist delete mode 100644 lib/abi/8.0/x86_64-unknown-linux-gnu.v1.abilist create mode 100644 lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist create mode 100644 lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist delete mode 100644 lib/abi/x86_64-apple-darwin.v1.abilist delete mode 100644 lib/abi/x86_64-apple-darwin.v2.abilist create mode 100644 lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist delete mode 100644 lib/abi/x86_64-unknown-linux-gnu.v1.abilist delete mode 100644 lib/libc++abi-new-delete.exp delete mode 100644 lib/libc++sjlj-abi.v1.exp delete mode 100644 lib/libc++sjlj-abi.v2.exp create mode 100644 src/atomic.cpp create mode 100644 src/barrier.cpp create mode 100644 src/chrono_system_time_init.h delete mode 100644 src/dso_handle.c create mode 100644 src/experimental/memory_resource_init_helper.h create mode 100644 src/filesystem/posix_compat.h create mode 100644 src/format.cpp create mode 100644 src/include/ryu/common.h create mode 100644 src/include/ryu/d2fixed.h create mode 100644 src/include/ryu/d2fixed_full_table.h create mode 100644 src/include/ryu/d2s.h create mode 100644 src/include/ryu/d2s_full_table.h create mode 100644 src/include/ryu/d2s_intrinsics.h create mode 100644 src/include/ryu/digit_table.h create mode 100644 src/include/ryu/f2s.h create mode 100644 src/include/ryu/ryu.h create mode 100644 src/include/sso_allocator.h create mode 100644 src/include/to_chars_floating_point.h create mode 100644 src/ios.instantiations.cpp create mode 100644 src/iostream_init.h create mode 100644 src/legacy_pointer_safety.cpp create mode 100644 src/random_shuffle.cpp create mode 100644 src/ryu/README.txt create mode 100644 src/ryu/d2fixed.cpp create mode 100644 src/ryu/d2s.cpp create mode 100644 src/ryu/f2s.cpp create mode 100644 src/support/ibm/mbsnrtowcs.cpp create mode 100644 src/support/ibm/wcsnrtombs.cpp create mode 100644 src/support/ibm/xlocale_zos.cpp create mode 100644 test/configs/apple-libc++-shared.cfg.in create mode 100644 test/configs/cmake-bridge.cfg.in create mode 100644 test/configs/ibm-libc++-shared.cfg.in create mode 100644 test/configs/legacy.cfg.in create mode 100644 test/configs/llvm-libc++-mingw.cfg.in create mode 100644 test/configs/llvm-libc++-shared-clangcl.cfg.in create mode 100644 test/configs/llvm-libc++-shared-gcc.cfg.in create mode 100644 test/configs/llvm-libc++-shared.cfg.in create mode 100644 test/configs/llvm-libc++-static-clangcl.cfg.in create mode 100644 test/configs/llvm-libc++-static.cfg.in delete mode 100644 test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.fail.cpp create mode 100644 test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.verify.cpp create mode 100644 test/libcxx/algorithms/nth_element_stability.pass.cpp create mode 100644 test/libcxx/algorithms/partial_sort_stability.pass.cpp create mode 100644 test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp create mode 100644 test/libcxx/algorithms/sort_stability.pass.cpp create mode 100644 test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp create mode 100644 test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp create mode 100644 test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp create mode 100644 test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp create mode 100644 test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp create mode 100644 test/libcxx/atomics/atomics.align/align.pass.cpp delete mode 100644 test/libcxx/atomics/atomics.align/align.pass.sh.cpp create mode 100644 test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp create mode 100644 test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp create mode 100644 test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp create mode 100644 test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp create mode 100644 test/libcxx/atomics/bit-int.verify.cpp delete mode 100644 test/libcxx/atomics/diagnose_invalid_memory_order.fail.cpp create mode 100644 test/libcxx/atomics/diagnose_invalid_memory_order.verify.cpp delete mode 100644 test/libcxx/atomics/libcpp-has-no-threads.fail.cpp delete mode 100644 test/libcxx/atomics/libcpp-has-no-threads.pass.cpp delete mode 100644 test/libcxx/containers/associative/non_const_comparator.fail.cpp create mode 100644 test/libcxx/containers/associative/non_const_comparator.incomplete.verify.cpp delete mode 100644 test/libcxx/containers/associative/non_const_comparator.pass.cpp create mode 100644 test/libcxx/containers/associative/non_const_comparator.verify.cpp create mode 100644 test/libcxx/containers/sequences/array/triviality.pass.cpp delete mode 100644 test/libcxx/containers/sequences/list/list.cons/db_move.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_back_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_cback_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_cfront_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_cindex_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_front_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_index_2.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_11.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_12.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_13.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_14.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_15.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/db_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp delete mode 100644 test/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.sh.cpp create mode 100644 test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp delete mode 100644 test/libcxx/containers/unord/non_const_comparator.fail.cpp create mode 100644 test/libcxx/containers/unord/non_const_comparator.incomplete.verify.cpp delete mode 100644 test/libcxx/containers/unord/non_const_comparator.pass.cpp create mode 100644 test/libcxx/containers/unord/non_const_comparator.verify.cpp create mode 100644 test/libcxx/containers/unord/unord.map/bucket_size.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_bucket.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_insert_hint_const_lvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_insert_hint_rvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_local_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_local_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/db_swap_1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/max_load_factor.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db3.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db4.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/bucket.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/bucket_size.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_insert_hint_const_lvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_insert_hint_rvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_local_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_local_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/db_swap_1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/max_load_factor.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db3.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db4.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/bucket.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/bucket_size.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_insert_hint_const_lvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_local_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_local_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/db_swap_1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.multiset/max_load_factor.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/bucket.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/bucket_size.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_insert_hint_const_lvalue.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_local_iterators_10.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_local_iterators_7.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_local_iterators_8.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_local_iterators_9.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/db_swap_1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp create mode 100644 test/libcxx/containers/unord/unord.set/max_load_factor.pass.cpp create mode 100644 test/libcxx/containers/views/span.cons/range.pass.cpp create mode 100644 test/libcxx/containers/views/span.cons/range.verify.cpp create mode 100644 test/libcxx/debug/extern-templates.sh.cpp delete mode 100644 test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp create mode 100644 test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.verify.cpp create mode 100644 test/libcxx/depr/depr.c.headers/math_h.compile.pass.cpp delete mode 100644 test/libcxx/depr/depr.c.headers/math_h.sh.cpp create mode 100644 test/libcxx/depr/depr.c.headers/no_fgetpos_fsetpos.verify.cpp create mode 100644 test/libcxx/depr/depr.c.headers/stdint_h.std_types_t.compile.pass.cpp create mode 100644 test/libcxx/depr/depr.c.headers/stdint_h.xopen_source.compile.pass.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp create mode 100644 test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp create mode 100644 test/libcxx/depr/depr.func.adaptor.typedefs/typedefs.depr_in_cxx17.verify.cpp delete mode 100644 test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.fail.cpp create mode 100644 test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/adjacent_find.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/all_of.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/any_of.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/binary_search.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/clamp.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/comp.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/comp_ref_type.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/copy_backward.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/copy_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/copy_n.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/count.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/count_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/equal.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/equal_range.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/fill.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/fill_n.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/find.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/find_end.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/find_first_of.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/find_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/find_if_not.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/for_each.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/for_each_n.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/generate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/generate_n.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/half_positive.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/in_in_out_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/in_in_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/in_out_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/includes.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/inplace_merge.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_heap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_heap_until.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_partitioned.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_permutation.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_sorted.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/is_sorted_until.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/iter_swap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/lexicographical_compare.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/lower_bound.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/make_heap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/max.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/max_element.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/merge.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/min.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/min_element.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/minmax.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/minmax_element.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/mismatch.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/move.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/move_backward.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/next_permutation.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/none_of.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/nth_element.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/partial_sort.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/partial_sort_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/partition.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/partition_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/partition_point.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/pop_heap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/prev_permutation.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/push_heap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/remove.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/remove_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/remove_copy_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/remove_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/replace.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/replace_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/replace_copy_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/replace_if.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/reverse.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/reverse_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/rotate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/rotate_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/sample.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/search.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/search_n.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/set_difference.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/set_intersection.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/set_symmetric_difference.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/set_union.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/shift_left.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/shift_right.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/shuffle.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/sift_down.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/sort.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/sort_heap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/stable_partition.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/stable_sort.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/swap_ranges.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/transform.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/unique.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/unique_copy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/unwrap_iter.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/algorithm/upper_bound.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/availability.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/bit/bit_cast.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/bit/byteswap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/bit_reference.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/bits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/charconv/chars_format.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/charconv/from_chars_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/charconv/to_chars_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/calendar.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/convert_to_timespec.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/duration.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/file_clock.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/high_resolution_clock.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/steady_clock.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/system_clock.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/chrono/time_point.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/common_comparison_category.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/compare_partial_order_fallback.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/compare_strong_order_fallback.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/compare_three_way.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/compare_three_way_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/compare_weak_order_fallback.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/ordering.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/partial_order.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/strong_order.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/synth_three_way.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/three_way_comparable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/compare/weak_order.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/arithmetic.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/assignable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/boolean_testable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/class_or_enum.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/common_reference_with.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/common_with.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/constructible.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/convertible_to.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/copyable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/derived_from.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/destructible.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/different_from.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/equality_comparable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/invocable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/movable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/predicate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/regular.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/relation.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/same_as.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/semiregular.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/swappable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/concepts/totally_ordered.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/coroutine/coroutine_handle.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/coroutine/coroutine_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/coroutine/noop_coroutine_handle.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/coroutine/trivial_awaitables.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/errc.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/copy_options.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/directory_entry.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/directory_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/directory_options.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/file_status.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/file_time_type.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/file_type.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/filesystem_error.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/operations.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/path.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/path_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/perm_options.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/perms.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/recursive_directory_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/space_info.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/filesystem/u8path.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_arg.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_args.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_context.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_error.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_fwd.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_parse_context.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_string.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/format_to_n_result.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_bool.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_char.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_floating_point.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_integer.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_integral.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_pointer.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/formatter_string.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/format/parser_std_format_spec.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/binary_function.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/binary_negate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/bind.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/bind_back.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/bind_front.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/binder1st.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/binder2nd.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/compose.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/default_searcher.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/function.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/hash.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/identity.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/invoke.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/is_transparent.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/mem_fn.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/mem_fun_ref.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/not_fn.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/operations.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/perfect_forward.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/pointer_to_binary_function.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/pointer_to_unary_function.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/ranges_operations.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/reference_wrapper.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/unary_function.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/unary_negate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/unwrap_ref.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/functional/weak_result_type.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/access.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/advance.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/back_insert_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/common_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/concepts.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/counted_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/data.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/default_sentinel.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/distance.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/empty.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/erase_if_container.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/front_insert_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/incrementable_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/indirectly_comparable.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/insert_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/istream_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/istreambuf_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/iter_move.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/iter_swap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/iterator_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/move_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/next.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/ostream_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/ostreambuf_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/prev.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/projected.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/readable_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/reverse_access.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/reverse_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/size.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/unreachable_sentinel.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/iterator/wrap_iter.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/locale.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/mbstate_t.h.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/addressof.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/allocation_guard.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/allocator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/allocator_arg_t.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/allocator_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/auto_ptr.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/compressed_pair.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/concepts.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/construct_at.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/pointer_traits.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/ranges_construct_at.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/ranges_uninitialized_algorithms.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/raw_storage_iterator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/shared_ptr.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/temporary_buffer.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/uninitialized_algorithms.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/unique_ptr.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/uses_allocator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/memory/voidify.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/mutex_base.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/node_handle.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/accumulate.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/adjacent_difference.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/exclusive_scan.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/gcd_lcm.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/inclusive_scan.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/inner_product.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/iota.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/midpoint.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/partial_sum.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/reduce.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/transform_exclusive_scan.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/transform_inclusive_scan.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/numeric/transform_reduce.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/bernoulli_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/binomial_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/cauchy_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/chi_squared_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/clamp_to_integral.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/default_random_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/discard_block_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/discrete_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/exponential_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/extreme_value_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/fisher_f_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/gamma_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/generate_canonical.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/geometric_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/independent_bits_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/is_seed_sequence.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/knuth_b.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/linear_congruential_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/log2.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/lognormal_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/mersenne_twister_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/negative_binomial_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/normal_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/piecewise_constant_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/piecewise_linear_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/poisson_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/random_device.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/ranlux.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/seed_seq.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/shuffle_order_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/student_t_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/subtract_with_carry_engine.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/uniform_int_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/uniform_random_bit_generator.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/uniform_real_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/random/weibull_distribution.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/access.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/all.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/common_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/concepts.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/copyable_box.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/counted.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/dangling.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/data.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/drop_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/empty.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/empty_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/enable_borrowed_range.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/enable_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/iota_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/join_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/non_propagating_cache.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/owning_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/range_adaptor.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/ref_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/reverse_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/single_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/size.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/subrange.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/take_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/transform_view.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/view_interface.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/ranges/views.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/split_buffer.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/std_stream.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/string.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/thread/poll_with_backoff.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/thread/timed_backoff_policy.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/tuple.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/as_const.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/auto_cast.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/cmp.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/declval.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/exchange.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/forward.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/in_place.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/integer_sequence.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/move.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/pair.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/piecewise_construct.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/priority_tag.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/rel_ops.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/swap.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/to_underlying.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/utility/transaction.module.verify.cpp create mode 100644 test/libcxx/diagnostics/detail.headers/variant/monostate.module.verify.cpp delete mode 100644 test/libcxx/diagnostics/enable_nodiscard.fail.cpp create mode 100644 test/libcxx/diagnostics/enable_nodiscard.verify.cpp delete mode 100644 test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.fail.cpp create mode 100644 test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.verify.cpp delete mode 100644 test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.fail.cpp create mode 100644 test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.verify.cpp delete mode 100644 test/libcxx/diagnostics/nodiscard_aftercxx17.fail.cpp create mode 100644 test/libcxx/diagnostics/nodiscard_aftercxx17.verify.cpp delete mode 100644 test/libcxx/diagnostics/nodiscard_extensions.fail.cpp create mode 100644 test/libcxx/diagnostics/nodiscard_extensions.verify.cpp delete mode 100644 test/libcxx/experimental/filesystem/deprecated.fail.cpp create mode 100644 test/libcxx/experimental/filesystem/deprecated.verify.cpp create mode 100644 test/libcxx/experimental/language.support/support.coroutines/dialect_support.pass.cpp delete mode 100644 test/libcxx/experimental/language.support/support.coroutines/dialect_support.sh.cpp create mode 100644 test/libcxx/experimental/language.support/support.coroutines/version.pass.cpp delete mode 100644 test/libcxx/experimental/language.support/support.coroutines/version.sh.cpp rename test/libcxx/extensions/hash/{specializations.fail.cpp => specializations.compile.fail.cpp} (100%) rename test/libcxx/extensions/hash_map/{const_iterator.fail.cpp => const_iterator.compile.fail.cpp} (100%) delete mode 100644 test/libcxx/extensions/nothing_to_do.pass.cpp create mode 100644 test/libcxx/fuzzing/fuzz.h create mode 100644 test/libcxx/fuzzing/make_heap.pass.cpp delete mode 100644 test/libcxx/fuzzing/nth_element.cpp create mode 100644 test/libcxx/fuzzing/nth_element.pass.cpp delete mode 100644 test/libcxx/fuzzing/partial_sort.cpp create mode 100644 test/libcxx/fuzzing/partial_sort.pass.cpp delete mode 100644 test/libcxx/fuzzing/partial_sort_copy.cpp create mode 100644 test/libcxx/fuzzing/partial_sort_copy.pass.cpp delete mode 100644 test/libcxx/fuzzing/partition.cpp create mode 100644 test/libcxx/fuzzing/partition.pass.cpp delete mode 100644 test/libcxx/fuzzing/partition_copy.cpp create mode 100644 test/libcxx/fuzzing/partition_copy.pass.cpp create mode 100644 test/libcxx/fuzzing/pop_heap.pass.cpp create mode 100644 test/libcxx/fuzzing/push_heap.pass.cpp create mode 100644 test/libcxx/fuzzing/random.pass.cpp create mode 100644 test/libcxx/fuzzing/regex.pass.cpp delete mode 100644 test/libcxx/fuzzing/regex_ECMAScript.cpp delete mode 100644 test/libcxx/fuzzing/regex_POSIX.cpp delete mode 100644 test/libcxx/fuzzing/regex_awk.cpp delete mode 100644 test/libcxx/fuzzing/regex_egrep.cpp delete mode 100644 test/libcxx/fuzzing/regex_extended.cpp delete mode 100644 test/libcxx/fuzzing/regex_grep.cpp create mode 100644 test/libcxx/fuzzing/search.pass.cpp delete mode 100644 test/libcxx/fuzzing/sort.cpp create mode 100644 test/libcxx/fuzzing/sort.pass.cpp delete mode 100644 test/libcxx/fuzzing/stable_partition.cpp create mode 100644 test/libcxx/fuzzing/stable_partition.pass.cpp delete mode 100644 test/libcxx/fuzzing/stable_sort.cpp create mode 100644 test/libcxx/fuzzing/stable_sort.pass.cpp delete mode 100644 test/libcxx/fuzzing/unique.cpp create mode 100644 test/libcxx/fuzzing/unique.pass.cpp delete mode 100644 test/libcxx/fuzzing/unique_copy.cpp create mode 100644 test/libcxx/fuzzing/unique_copy.pass.cpp rename test/{pretty_printers => libcxx/gdb}/gdb_pretty_printer_test.py (85%) rename test/{pretty_printers => libcxx/gdb}/gdb_pretty_printer_test.sh.cpp (84%) create mode 100644 test/libcxx/inclusions/algorithm.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/array.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/bitset.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/chrono.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/cinttypes.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/complex.h.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/coroutine.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/deque.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/filesystem.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/forward_list.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/ios.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/iostream.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/iterator.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/list.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/map.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/memory.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/optional.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/queue.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/random.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/ranges.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/regex.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/set.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/stack.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/string.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/string_view.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/system_error.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/tgmath.h.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/thread.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/tuple.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/typeindex.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/unordered_map.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/unordered_set.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/utility.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/valarray.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/variant.inclusions.compile.pass.cpp create mode 100644 test/libcxx/inclusions/vector.inclusions.compile.pass.cpp delete mode 100644 test/libcxx/input.output/file.streams/c.files/no.global.filesystem.namespace/fopen.fail.cpp delete mode 100644 test/libcxx/input.output/file.streams/c.files/no.global.filesystem.namespace/rename.fail.cpp create mode 100644 test/libcxx/input.output/file.streams/lit.local.cfg create mode 100644 test/libcxx/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.pass.cpp delete mode 100644 test/libcxx/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.sh.cpp delete mode 100644 test/libcxx/input.output/filesystems/class.path/path.itr/reverse_iterator_produces_diagnostic.fail.cpp create mode 100644 test/libcxx/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp create mode 100644 test/libcxx/input.output/filesystems/convert_file_time.pass.cpp delete mode 100644 test/libcxx/input.output/filesystems/convert_file_time.sh.cpp create mode 100644 test/libcxx/input.output/iostream.format/lit.local.cfg create mode 100644 test/libcxx/input.output/iostream.objects/lit.local.cfg create mode 100644 test/libcxx/input.output/iostreams.base/lit.local.cfg create mode 100644 test/libcxx/input.output/stream.buffers/lit.local.cfg create mode 100644 test/libcxx/input.output/string.streams/lit.local.cfg create mode 100644 test/libcxx/iterators/contiguous_iterators.pass.cpp create mode 100644 test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.concepts/integer_like.compile.pass.cpp create mode 100644 test/libcxx/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp delete mode 100644 test/libcxx/iterators/trivial_iterators.pass.cpp delete mode 100644 test/libcxx/language.support/has_c11_features.pass.cpp create mode 100644 test/libcxx/language.support/support.dynamic/aligned_alloc_availability.verify.cpp create mode 100644 test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp delete mode 100644 test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp create mode 100644 test/libcxx/language.support/support.rtti/type.info/type_info.comparison.apple.compile.pass.cpp create mode 100644 test/libcxx/language.support/support.rtti/type.info/type_info.comparison.merged.sh.cpp create mode 100644 test/libcxx/language.support/support.rtti/type.info/type_info.comparison.unmerged.sh.cpp create mode 100644 test/libcxx/language.support/timespec_get.xopen.compile.pass.cpp create mode 100644 test/libcxx/libcpp_freestanding.sh.cpp create mode 100644 test/libcxx/lint/lint_cmakelists.sh.py create mode 100644 test/libcxx/lint/lint_headers.sh.py create mode 100644 test/libcxx/lint/lint_modulemap.sh.py create mode 100644 test/libcxx/lint/lit.local.cfg create mode 100644 test/libcxx/localization/lit.local.cfg create mode 100644 test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp create mode 100644 test/libcxx/memory/aligned_allocation_macro.compile.pass.cpp delete mode 100644 test/libcxx/memory/aligned_allocation_macro.pass.cpp create mode 100644 test/libcxx/memory/allocator_void.trivial.compile.pass.cpp create mode 100644 test/libcxx/memory/allocator_volatile.verify.cpp create mode 100644 test/libcxx/memory/compressed_pair/compressed_pair.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/shared_ptr_arg.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/unique_ptr_arg.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/unique_ptr_array.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/unique_ptr_destruction_order.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/unique_ptr_ret.pass.cpp create mode 100644 test/libcxx/memory/trivial_abi/weak_ptr_ret.pass.cpp create mode 100644 test/libcxx/min_max_macros.compile.pass.cpp delete mode 100644 test/libcxx/min_max_macros.sh.cpp delete mode 100644 test/libcxx/modules/cinttypes_exports.sh.cpp delete mode 100644 test/libcxx/modules/clocale_exports.sh.cpp delete mode 100644 test/libcxx/modules/cstdint_exports.sh.cpp delete mode 100644 test/libcxx/modules/inttypes_h_exports.sh.cpp delete mode 100644 test/libcxx/modules/stdint_h_exports.sh.cpp create mode 100644 test/libcxx/nasty_macros.compile.pass.cpp create mode 100644 test/libcxx/no_assert_include.compile.pass.cpp delete mode 100644 test/libcxx/no_assert_include.sh.cpp create mode 100644 test/libcxx/numerics/c.math/fdelayed-template-parsing.pass.cpp delete mode 100644 test/libcxx/numerics/c.math/fdelayed-template-parsing.sh.cpp create mode 100644 test/libcxx/numerics/rand/rand.device/has-no-random-device.verify.cpp create mode 100644 test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp create mode 100644 test/libcxx/ranges/range.access/end.incomplete_type.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.common.view/adaptor.nodiscard.verify.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.copy.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.move.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.default.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.in_place.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/deref.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/has_value.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/no_unique_address.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/properties.compile.pass.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.copy.wrap/types.h create mode 100644 test/libcxx/ranges/range.adaptors/range.counted/adaptor.nodiscard.verify.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.reverse/adaptor.nodiscard.verify.cpp create mode 100644 test/libcxx/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/assign.copy.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/assign.move.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/constraints.compile.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/ctor.copy.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/ctor.default.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/ctor.move.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/deref.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/emplace.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/emplace_from.pass.cpp create mode 100644 test/libcxx/ranges/range.nonprop.cache/has_value.pass.cpp create mode 100644 test/libcxx/ranges/range.utility.helpers/different_from.compile.pass.cpp create mode 100644 test/libcxx/ranges/range.utility.helpers/has_arrow.compile.pass.cpp create mode 100644 test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp create mode 100644 test/libcxx/ranges/version.compile.pass.cpp create mode 100644 test/libcxx/selftest/additional_compile_flags/substitutes-in-compile-flags.sh.cpp create mode 100644 test/libcxx/selftest/additional_compile_flags/substitutes-in-run.sh.cpp create mode 100644 test/libcxx/selftest/compile.fail.cpp/compile-error.compile.fail.cpp create mode 100644 test/libcxx/selftest/compile.fail.cpp/compile-success.compile.fail.cpp create mode 100644 test/libcxx/selftest/compile.pass.cpp/compile-error.compile.pass.cpp create mode 100644 test/libcxx/selftest/compile.pass.cpp/compile-success.compile.pass.cpp create mode 100644 test/libcxx/selftest/compile.pass.cpp/link-error.compile.pass.cpp create mode 100644 test/libcxx/selftest/compile.pass.cpp/run-error.compile.pass.cpp create mode 100644 test/libcxx/selftest/convenience_substitutions/build_run.sh.cpp create mode 100644 test/libcxx/selftest/dsl/dsl.sh.py create mode 100644 test/libcxx/selftest/dsl/lit.local.cfg create mode 100644 test/libcxx/selftest/fail.cpp/compile-failure.fail.cpp create mode 100644 test/libcxx/selftest/fail.cpp/compile-success.fail.cpp create mode 100644 test/libcxx/selftest/fail.cpp/no-diagnostics-unmarked.fail.cpp create mode 100644 test/libcxx/selftest/fail.cpp/no-diagnostics.fail.cpp create mode 100644 test/libcxx/selftest/fail.cpp/right-diagnostic.fail.cpp create mode 100644 test/libcxx/selftest/fail.cpp/wrong-diagnostic.fail.cpp rename test/{std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/afile3 => libcxx/selftest/file_dependencies/a.txt} (100%) create mode 100644 test/libcxx/selftest/file_dependencies/absolute-and-relative-paths.sh.cpp rename test/{std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/dir3/file5 => libcxx/selftest/file_dependencies/dir/b.txt} (100%) create mode 100644 test/libcxx/selftest/file_dependencies/substitute-in-dependencies.sh.cpp create mode 100644 test/libcxx/selftest/link.fail.cpp/compile-error.link.fail.cpp create mode 100644 test/libcxx/selftest/link.fail.cpp/link-error.link.fail.cpp create mode 100644 test/libcxx/selftest/link.fail.cpp/link-success.link.fail.cpp create mode 100644 test/libcxx/selftest/link.pass.cpp/compile-error.link.pass.cpp create mode 100644 test/libcxx/selftest/link.pass.cpp/link-error.link.pass.cpp create mode 100644 test/libcxx/selftest/link.pass.cpp/link-success.link.pass.cpp create mode 100644 test/libcxx/selftest/link.pass.cpp/run-error.link.pass.cpp delete mode 100644 test/libcxx/selftest/not_test.sh.cpp create mode 100644 test/libcxx/selftest/pass.cpp/compile-error.pass.cpp create mode 100644 test/libcxx/selftest/pass.cpp/link-error.pass.cpp create mode 100644 test/libcxx/selftest/pass.cpp/run-error.pass.cpp create mode 100644 test/libcxx/selftest/pass.cpp/run-success.pass.cpp create mode 100644 test/libcxx/selftest/pass.cpp/werror.pass.cpp create mode 100644 test/libcxx/selftest/pass.mm/compile-error.pass.mm create mode 100644 test/libcxx/selftest/pass.mm/link-error.pass.mm create mode 100644 test/libcxx/selftest/pass.mm/no-arc.pass.mm create mode 100644 test/libcxx/selftest/pass.mm/run-error.pass.mm create mode 100644 test/libcxx/selftest/pass.mm/run-success.pass.mm create mode 100644 test/libcxx/selftest/pass.mm/use-objective-cxx.pass.mm create mode 100644 test/libcxx/selftest/remote-substitutions.sh.cpp create mode 100644 test/libcxx/selftest/sh.cpp/empty.sh.cpp create mode 100644 test/libcxx/selftest/sh.cpp/run-error.sh.cpp create mode 100644 test/libcxx/selftest/sh.cpp/run-success.sh.cpp create mode 100644 test/libcxx/selftest/sh.cpp/substitutions.sh.cpp create mode 100644 test/libcxx/selftest/sh.cpp/werror.sh.cpp create mode 100644 test/libcxx/selftest/shell-no-escape-builtins.sh.cpp delete mode 100644 test/libcxx/selftest/test.arc.fail.mm delete mode 100644 test/libcxx/selftest/test.arc.pass.mm delete mode 100644 test/libcxx/selftest/test.fail.cpp delete mode 100644 test/libcxx/selftest/test.fail.mm delete mode 100644 test/libcxx/selftest/test.pass.cpp delete mode 100644 test/libcxx/selftest/test.pass.mm delete mode 100644 test/libcxx/selftest/test.sh.cpp create mode 100644 test/libcxx/selftest/tmpdir-exists.sh.cpp create mode 100644 test/libcxx/selftest/verify.cpp/no-diagnostics-unmarked.verify.cpp create mode 100644 test/libcxx/selftest/verify.cpp/no-diagnostics.verify.cpp create mode 100644 test/libcxx/selftest/verify.cpp/no-werror.verify.cpp create mode 100644 test/libcxx/selftest/verify.cpp/right-diagnostic.verify.cpp create mode 100644 test/libcxx/selftest/verify.cpp/wrong-diagnostic.verify.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/back.const.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/back.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_back.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_back_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cback.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cback_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cfront.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cfront_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cindex.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_cindex_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_front.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_front_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_index.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/db_index_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/front.const.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/front.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/index.const.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.access/index.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.capacity/PR53170.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_10.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_11.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_12.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_13.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_14.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_15.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_2.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_3.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_4.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_5.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_6.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_7.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_8.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.iterators/db_iterators_9.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink.pass.cpp delete mode 100644 test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink_db1.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_db3.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_db4.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db5.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db6.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db7.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db8.pass.cpp create mode 100644 test/libcxx/strings/basic.string/string.modifiers/insert_iter_iter_iter_db1.pass.cpp delete mode 100644 test/libcxx/strings/iterators.exceptions.pass.cpp delete mode 100644 test/libcxx/strings/iterators.noexcept.pass.cpp create mode 100644 test/libcxx/thread/atomic.availability.verify.cpp create mode 100644 test/libcxx/thread/barrier.availability.verify.cpp create mode 100644 test/libcxx/thread/latch.availability.verify.cpp create mode 100644 test/libcxx/thread/semaphore.availability.verify.cpp create mode 100644 test/libcxx/thread/thread.barrier/version.compile.pass.cpp create mode 100644 test/libcxx/thread/thread.latch/version.compile.pass.cpp delete mode 100644 test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp create mode 100644 test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.verify.cpp create mode 100644 test/libcxx/thread/thread.semaphore/version.compile.pass.cpp create mode 100644 test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.signals.pass.cpp create mode 100644 test/libcxx/type_traits/is_scalar.objc.pass.mm create mode 100644 test/libcxx/utilities/any/allocator.pass.cpp create mode 100644 test/libcxx/utilities/charconv/charconv.to.chars/availability.fail.cpp create mode 100644 test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp create mode 100644 test/libcxx/utilities/format/format.arguments/format.arg/visit_format_arg.pass.cpp create mode 100644 test/libcxx/utilities/format/format.arguments/format.args/get.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/concepts_precision.h create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_bool.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_char.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_floating_point.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_integer.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_pointer.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_string.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_string_non_unicode.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/std_format_spec_string_unicode.pass.cpp create mode 100644 test/libcxx/utilities/format/format.string/format.string.std/test_exception.h create mode 100644 test/libcxx/utilities/format/version.compile.pass.cpp create mode 100644 test/libcxx/utilities/function.objects/func.bind.partial/bind_back.pass.cpp create mode 100644 test/libcxx/utilities/function.objects/func.bind.partial/compose.pass.cpp create mode 100644 test/libcxx/utilities/function.objects/func.blocks.sh.cpp create mode 100644 test/libcxx/utilities/function.objects/func.wrap/depr_in_cxx03.verify.cpp create mode 100644 test/libcxx/utilities/memory/pointer.conversion/to_address.pass.cpp create mode 100644 test/libcxx/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.cpp create mode 100644 test/libcxx/utilities/memory/pointer.conversion/to_address_on_function.verify.cpp create mode 100644 test/libcxx/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp delete mode 100644 test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp delete mode 100644 test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp create mode 100644 test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.cpp delete mode 100644 test/libcxx/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp delete mode 100644 test/libcxx/utilities/meta/meta.unary/meta.unary.prop/missing_is_aggregate_trait.fail.cpp create mode 100644 test/libcxx/utilities/optional/block.objc.pass.mm create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp create mode 100644 test/libcxx/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp delete mode 100644 test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp delete mode 100644 test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp delete mode 100644 test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp delete mode 100644 test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp create mode 100644 test/libcxx/utilities/transaction.pass.cpp create mode 100644 test/libcxx/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp create mode 100644 test/libcxx/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp delete mode 100644 test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/disable_reduced_arity_initialization_extension.pass.cpp delete mode 100644 test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/empty_tuple_trivial.pass.cpp delete mode 100644 test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/enable_reduced_arity_initialization_extension.pass.cpp create mode 100644 test/libcxx/vendor/apple/system-install-properties.sh.cpp delete mode 100644 test/lit.cfg create mode 100644 test/lit.cfg.py delete mode 100644 test/lit.site.cfg.in delete mode 100644 test/nothing_to_do.pass.cpp create mode 100644 test/std/algorithms/alg.modifying.operations/alg.move/contiguous_trivial_optimization.pass.cpp create mode 100644 test/std/algorithms/alg.modifying.operations/alg.shift/shift_left.pass.cpp create mode 100644 test/std/algorithms/alg.modifying.operations/alg.shift/shift_right.pass.cpp delete mode 100644 test/std/algorithms/alg.modifying.operations/nothing_to_do.pass.cpp delete mode 100644 test/std/algorithms/alg.nonmodifying/nothing_to_do.pass.cpp delete mode 100644 test/std/algorithms/alg.sorting/alg.binary.search/nothing_to_do.pass.cpp delete mode 100644 test/std/algorithms/alg.sorting/alg.heap.operations/nothing_to_do.pass.cpp delete mode 100644 test/std/algorithms/alg.sorting/alg.set.operations/nothing_to_do.pass.cpp delete mode 100644 test/std/algorithms/alg.sorting/alg.sort/nothing_to_do.pass.cpp create mode 100644 test/std/algorithms/alg.sorting/alg.sort/sort/sort_constexpr.pass.cpp create mode 100644 test/std/algorithms/alg.sorting/alg.sort/sort/sort_constexpr_comp.pass.cpp delete mode 100644 test/std/algorithms/alg.sorting/nothing_to_do.pass.cpp create mode 100644 test/std/algorithms/alg.sorting/sortable_helpers.h create mode 100644 test/std/algorithms/algorithms.results/in_in_out_result.pass.cpp create mode 100644 test/std/algorithms/algorithms.results/in_in_result.pass.cpp create mode 100644 test/std/algorithms/algorithms.results/in_out_result.compile.pass.cpp create mode 100644 test/std/algorithms/algorithms.results/in_out_result.pass.cpp create mode 100644 test/std/algorithms/algorithms.results/no_unique_address.compile.pass.cpp create mode 100644 test/std/algorithms/robust_against_adl.compile.pass.cpp create mode 100644 test/std/algorithms/robust_against_adl_on_new.pass.cpp create mode 100644 test/std/algorithms/robust_re_difference_type.compile.pass.cpp create mode 100644 test/std/atomics/atomics.flag/atomic_flag_test.pass.cpp create mode 100644 test/std/atomics/atomics.flag/atomic_flag_test_explicit.pass.cpp rename test/std/atomics/atomics.flag/{copy_assign.fail.cpp => copy_assign.compile.fail.cpp} (100%) rename test/std/atomics/atomics.flag/{copy_ctor.fail.cpp => copy_ctor.compile.fail.cpp} (100%) rename test/std/atomics/atomics.flag/{copy_volatile_assign.fail.cpp => copy_volatile_assign.compile.fail.cpp} (100%) delete mode 100644 test/std/atomics/atomics.general/nothing_to_do.pass.cpp create mode 100644 test/std/atomics/atomics.general/replace_failure_order_codegen.sh.cpp create mode 100644 test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp create mode 100644 test/std/atomics/atomics.types.generic/copy_semantics_traits.pass.cpp create mode 100644 test/std/atomics/atomics.types.generic/standard_layout.compile.pass.cpp create mode 100644 test/std/atomics/atomics.types.generic/throw.pass.cpp delete mode 100644 test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp create mode 100644 test/std/atomics/atomics.types.generic/trivially_copyable.verify.cpp delete mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.ptr.volatile.verify.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.volatile.verify.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.req/dtor.pass.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp create mode 100644 test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp delete mode 100644 test/std/atomics/atomics.types.operations/nothing_to_do.pass.cpp create mode 100644 test/std/atomics/types.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.equiv/equivalence_relation.subsumption.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.invocable/invocable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.predicate/predicate.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.predicate/predicate.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.predicate/predicate.subsumption.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.regularinvocable/regular_invocable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.relation/relation.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.relation/relation.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.relation/relation.subsumption.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.relation/relation.subsumption.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.compile.pass.cpp create mode 100644 test/std/concepts/concepts.callable/concept.strictweakorder/strict_weak_order.subsumption.pass.cpp create mode 100644 test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp create mode 100644 test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.pass.cpp create mode 100644 test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.assignable/assignable_from.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.constructible/constructible_from.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.convertible/convertible_to.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.copyconstructible/copy_constructible.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.default.init/default_initializable.verify.cpp create mode 100644 test/std/concepts/concepts.lang/concept.derived/derived_from.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.destructible/destructible.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.moveconstructible/move_constructible.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.same/same_as.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.swappable/swappable.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concepts.arithmetic/arithmetic.h create mode 100644 test/std/concepts/concepts.lang/concepts.arithmetic/floating_point.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concepts.arithmetic/integral.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concepts.arithmetic/signed_integral.pass.cpp create mode 100644 test/std/concepts/concepts.lang/concepts.arithmetic/unsigned_integral.pass.cpp create mode 100644 test/std/concepts/concepts.object/copyable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.object/movable.compile.pass.cpp create mode 100644 test/std/concepts/concepts.object/regular.compile.pass.cpp create mode 100644 test/std/concepts/concepts.object/semiregular.compile.pass.cpp rename test/std/containers/associative/map/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/map/get_allocator.pass.cpp create mode 100644 test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/containers/associative/map/map.access/empty.fail.cpp create mode 100644 test/std/containers/associative/map/map.access/empty.verify.cpp rename test/std/containers/associative/map/map.cons/{compare_copy_constructible.fail.cpp => compare_copy_constructible.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/map/map.cons/copy_assign.addressof.compile.pass.cpp create mode 100644 test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp create mode 100644 test/std/containers/associative/map/map.observers/key_comp.pass.cpp create mode 100644 test/std/containers/associative/map/map.observers/value_comp.pass.cpp rename test/std/containers/associative/map/{ => map.ops}/contains.pass.cpp (97%) create mode 100644 test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp create mode 100644 test/std/containers/associative/map/map.ops/count1.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/count1.fail.cpp create mode 100644 test/std/containers/associative/map/map.ops/count2.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/count2.fail.cpp create mode 100644 test/std/containers/associative/map/map.ops/count3.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/count3.fail.cpp create mode 100644 test/std/containers/associative/map/map.ops/equal_range1.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/equal_range1.fail.cpp create mode 100644 test/std/containers/associative/map/map.ops/equal_range2.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/equal_range2.fail.cpp create mode 100644 test/std/containers/associative/map/map.ops/equal_range3.compile.fail.cpp delete mode 100644 test/std/containers/associative/map/map.ops/equal_range3.fail.cpp rename test/std/containers/associative/map/map.ops/{find1.fail.cpp => find1.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{find2.fail.cpp => find2.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{find3.fail.cpp => find3.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{lower_bound1.fail.cpp => lower_bound1.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{lower_bound2.fail.cpp => lower_bound2.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{lower_bound3.fail.cpp => lower_bound3.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{upper_bound1.fail.cpp => upper_bound1.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{upper_bound2.fail.cpp => upper_bound2.compile.fail.cpp} (100%) rename test/std/containers/associative/map/map.ops/{upper_bound3.fail.cpp => upper_bound3.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/map/map.value_compare/invoke.pass.cpp create mode 100644 test/std/containers/associative/map/map.value_compare/types.pass.cpp create mode 100644 test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp rename test/std/containers/associative/multimap/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) delete mode 100644 test/std/containers/associative/multimap/empty.fail.cpp create mode 100644 test/std/containers/associative/multimap/empty.verify.cpp create mode 100644 test/std/containers/associative/multimap/get_allocator.pass.cpp create mode 100644 test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp rename test/std/containers/associative/multimap/multimap.cons/{compare_copy_constructible.fail.cpp => compare_copy_constructible.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/multimap/multimap.cons/copy_assign.addressof.compile.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.nonmember/op_compare.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.observers/key_comp.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.observers/value_comp.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/count1.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/count2.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/count3.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range1.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range2.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp create mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range3.compile.fail.cpp delete mode 100644 test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp rename test/std/containers/associative/multimap/multimap.ops/{find1.fail.cpp => find1.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{find2.fail.cpp => find2.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{find3.fail.cpp => find3.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{lower_bound1.fail.cpp => lower_bound1.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{lower_bound2.fail.cpp => lower_bound2.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{lower_bound3.fail.cpp => lower_bound3.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{upper_bound1.fail.cpp => upper_bound1.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{upper_bound2.fail.cpp => upper_bound2.compile.fail.cpp} (100%) rename test/std/containers/associative/multimap/multimap.ops/{upper_bound3.fail.cpp => upper_bound3.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/multimap/multimap.value_compare/invoke.pass.cpp create mode 100644 test/std/containers/associative/multimap/multimap.value_compare/types.pass.cpp create mode 100644 test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp rename test/std/containers/associative/multiset/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) delete mode 100644 test/std/containers/associative/multiset/empty.fail.cpp create mode 100644 test/std/containers/associative/multiset/empty.verify.cpp create mode 100644 test/std/containers/associative/multiset/get_allocator.pass.cpp create mode 100644 test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp rename test/std/containers/associative/multiset/multiset.cons/{compare_copy_constructible.fail.cpp => compare_copy_constructible.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/multiset/multiset.cons/copy_assign.addressof.compile.pass.cpp create mode 100644 test/std/containers/associative/multiset/multiset.nonmember/op_compare.pass.cpp create mode 100644 test/std/containers/associative/multiset/multiset.observers/comp.pass.cpp create mode 100644 test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp rename test/std/containers/associative/set/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/set/contains_transparent.pass.cpp delete mode 100644 test/std/containers/associative/set/empty.fail.cpp create mode 100644 test/std/containers/associative/set/empty.verify.cpp create mode 100644 test/std/containers/associative/set/get_allocator.pass.cpp create mode 100644 test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp rename test/std/containers/associative/set/set.cons/{compare_copy_constructible.fail.cpp => compare_copy_constructible.compile.fail.cpp} (100%) create mode 100644 test/std/containers/associative/set/set.cons/copy_assign.addressof.compile.pass.cpp create mode 100644 test/std/containers/associative/set/set.nonmember/op_compare.pass.cpp create mode 100644 test/std/containers/associative/set/set.observers/comp.pass.cpp delete mode 100644 test/std/containers/container.adaptors/nothing_to_do.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_iter_iter_alloc.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_iter_iter_comp_alloc.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_iter_iter_comp_cont_alloc.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons.alloc/ctor_iter_iter_comp_rcont_alloc.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_iter_constraint.compile.pass.cpp delete mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.members/empty.fail.cpp create mode 100644 test/std/containers/container.adaptors/priority.queue/priqueue.members/empty.verify.cpp rename test/std/containers/container.adaptors/priority.queue/{types.fail.cpp => types.compile.fail.cpp} (100%) create mode 100644 test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp create mode 100644 test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp create mode 100644 test/std/containers/container.adaptors/queue/queue.defn/assign_copy.addressof.compile.pass.cpp delete mode 100644 test/std/containers/container.adaptors/queue/queue.defn/empty.fail.cpp create mode 100644 test/std/containers/container.adaptors/queue/queue.defn/empty.verify.cpp rename test/std/containers/container.adaptors/queue/queue.defn/{types.fail.cpp => types.compile.fail.cpp} (100%) create mode 100644 test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp create mode 100644 test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp delete mode 100644 test/std/containers/container.adaptors/stack/stack.defn/empty.fail.cpp create mode 100644 test/std/containers/container.adaptors/stack/stack.defn/empty.verify.cpp rename test/std/containers/container.adaptors/stack/stack.defn/{types.fail.cpp => types.compile.fail.cpp} (100%) create mode 100644 test/std/containers/container.node/node_handle.nodiscard.verify.cpp delete mode 100644 test/std/containers/container.requirements/associative.reqmts/nothing_to_do.pass.cpp delete mode 100644 test/std/containers/container.requirements/container.requirements.general/nothing_to_do.pass.cpp delete mode 100644 test/std/containers/container.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/containers/container.requirements/unord.req/nothing_to_do.pass.cpp create mode 100644 test/std/containers/iterator.rel_ops.compile.pass.cpp delete mode 100644 test/std/containers/nothing_to_do.pass.cpp create mode 100644 test/std/containers/sequences/array/aggregate.pass.cpp delete mode 100644 test/std/containers/sequences/array/array.cons/default.pass.cpp create mode 100644 test/std/containers/sequences/array/array.cons/implicit_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/array/array.cons/initialization.pass.cpp delete mode 100644 test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp create mode 100644 test/std/containers/sequences/array/array.creation/to_array.fail.cpp create mode 100644 test/std/containers/sequences/array/array.creation/to_array.pass.cpp create mode 100644 test/std/containers/sequences/array/at_const.pass.cpp delete mode 100644 test/std/containers/sequences/array/begin.pass.cpp delete mode 100644 test/std/containers/sequences/array/empty.fail.cpp create mode 100644 test/std/containers/sequences/array/empty.verify.cpp create mode 100644 test/std/containers/sequences/array/front_back_const.pass.cpp create mode 100644 test/std/containers/sequences/array/indexing_const.pass.cpp create mode 100644 test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp rename test/std/containers/sequences/deque/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/sequences/deque/compare.pass.cpp delete mode 100644 test/std/containers/sequences/deque/deque.capacity/empty.fail.cpp create mode 100644 test/std/containers/sequences/deque/deque.capacity/empty.verify.cpp create mode 100644 test/std/containers/sequences/deque/deque.cons/move_assign.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/deque/get_allocator.pass.cpp create mode 100644 test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp rename test/std/containers/sequences/forwardlist/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) delete mode 100644 test/std/containers/sequences/forwardlist/empty.fail.cpp create mode 100644 test/std/containers/sequences/forwardlist/empty.verify.cpp rename test/std/containers/sequences/forwardlist/forwardlist.cons/{alloc.fail.cpp => alloc.compile.fail.cpp} (100%) create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp delete mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/get_allocator.pass.cpp create mode 100644 test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp rename test/std/containers/sequences/list/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/sequences/list/compare.pass.cpp create mode 100644 test/std/containers/sequences/list/get_allocator.pass.cpp create mode 100644 test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/containers/sequences/list/list.capacity/empty.fail.cpp create mode 100644 test/std/containers/sequences/list/list.capacity/empty.verify.cpp create mode 100644 test/std/containers/sequences/list/list.cons/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.cons/assign_move.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.cons/dtor.pass.cpp create mode 100644 test/std/containers/sequences/list/list.modifiers/emplace.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.modifiers/erase_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.modifiers/insert_iter_value.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.ops/merge_comp.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.ops/splice_pos_list_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/list.special/swap.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/containers/sequences/nothing_to_do.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/compare.pass.cpp delete mode 100644 test/std/containers/sequences/vector.bool/empty.fail.cpp create mode 100644 test/std/containers/sequences/vector.bool/empty.verify.cpp create mode 100644 test/std/containers/sequences/vector.bool/get_allocator.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/assign_bool.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/assign_copy.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/ctor_copy.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/flip.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/operator_bool.pass.cpp create mode 100644 test/std/containers/sequences/vector.bool/reference/triviality.compile.pass.cpp rename test/std/containers/sequences/vector/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/sequences/vector/compare.pass.cpp create mode 100644 test/std/containers/sequences/vector/get_allocator.pass.cpp create mode 100644 test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/reverse_iterators.pass.cpp delete mode 100644 test/std/containers/sequences/vector/vector.capacity/empty.fail.cpp create mode 100644 test/std/containers/sequences/vector/vector.capacity/empty.verify.cpp create mode 100644 test/std/containers/sequences/vector/vector.cons/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.cons/assign_move.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.cons/copy.move_only.verify.cpp create mode 100644 test/std/containers/sequences/vector/vector.cons/move.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/emplace.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/erase_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_lvalue.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.addressof.compile.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.addressof.compile.pass.cpp delete mode 100644 test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp create mode 100644 test/std/containers/sequences/vector/vector.special/swap.addressof.compile.pass.cpp rename test/std/containers/unord/unord.map/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.map/contains.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.map/count.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/empty.fail.cpp create mode 100644 test/std/containers/unord/unord.map/empty.verify.cpp create mode 100644 test/std/containers/unord/unord.map/equal_range.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.map/find.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.map/get_allocator.pass.cpp create mode 100644 test/std/containers/unord/unord.map/iterator.operators.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/compare_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/compare_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/hash_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/hash_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/move.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/size.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_const_iter.addressof.compile.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db3.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db4.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue_constructible_value_type.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue_value_type.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.modifiers/try_emplace_hint.addressof.compile.pass.cpp delete mode 100644 test/std/containers/unord/unord.map/unord.map.swap/db_swap_1.pass.cpp create mode 100644 test/std/containers/unord/unord.map/unord.map.swap/swap.addressof.compile.pass.cpp rename test/std/containers/unord/unord.multimap/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.multimap/contains.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/count.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/db_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/db_iterators_8.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/empty.fail.cpp create mode 100644 test/std/containers/unord/unord.multimap/empty.verify.cpp create mode 100644 test/std/containers/unord/unord.multimap/equal_range.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/find.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/get_allocator.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp rename test/std/containers/unord/unord.multimap/{iterators.fail.cpp => iterators.compile.fail.cpp} (100%) rename test/std/containers/unord/unord.multimap/{local_iterators.fail.cpp => local_iterators.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/compare_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/compare_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/hash_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/hash_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp create mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.addressof.compile.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db3.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db4.pass.cpp delete mode 100644 test/std/containers/unord/unord.multimap/unord.multimap.swap/db_swap_1.pass.cpp rename test/std/containers/unord/unord.multiset/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.multiset/contains.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/count.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/db_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/db_iterators_8.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/empty.fail.cpp create mode 100644 test/std/containers/unord/unord.multiset/empty.verify.cpp create mode 100644 test/std/containers/unord/unord.multiset/equal_range.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp delete mode 100644 test/std/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/find.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/get_allocator.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp rename test/std/containers/unord/unord.multiset/{iterators.fail.cpp => iterators.compile.fail.cpp} (100%) rename test/std/containers/unord/unord.multiset/{local_iterators.fail.cpp => local_iterators.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/compare_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/compare_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/hash_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/hash_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp delete mode 100644 test/std/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp rename test/std/containers/unord/unord.set/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.set/contains.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.set/count.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/db_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/db_iterators_8.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/db_local_iterators_7.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/db_local_iterators_8.pass.cpp create mode 100644 test/std/containers/unord/unord.set/emplace_hint.addressof.compile.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/empty.fail.cpp create mode 100644 test/std/containers/unord/unord.set/empty.verify.cpp create mode 100644 test/std/containers/unord/unord.set/equal_range.transparent.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp delete mode 100644 test/std/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp create mode 100644 test/std/containers/unord/unord.set/find.transparent.pass.cpp create mode 100644 test/std/containers/unord/unord.set/get_allocator.pass.cpp create mode 100644 test/std/containers/unord/unord.set/insert_hint_const_lvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/insert_hint_rvalue.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/iterator.operators.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp rename test/std/containers/unord/unord.set/{iterators.fail.cpp => iterators.compile.fail.cpp} (100%) rename test/std/containers/unord/unord.set/{local_iterators.fail.cpp => local_iterators.compile.fail.cpp} (100%) create mode 100644 test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/compare_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/compare_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/hash_copy_constructible.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/hash_copy_constructible.fail.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/move.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.addressof.compile.pass.cpp create mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/size.compile.fail.cpp delete mode 100644 test/std/containers/unord/unord.set/unord.set.cnstr/size.fail.cpp delete mode 100644 test/std/containers/unord/unord.set/unord.set.swap/db_swap_1.pass.cpp create mode 100644 test/std/containers/views/enable_borrowed_range.compile.pass.cpp create mode 100644 test/std/containers/views/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/containers/views/span.cons/container.fail.cpp delete mode 100644 test/std/containers/views/span.cons/container.pass.cpp create mode 100644 test/std/containers/views/span.cons/initializer_list.pass.cpp create mode 100644 test/std/containers/views/span.cons/iterator_len.pass.cpp create mode 100644 test/std/containers/views/span.cons/iterator_len.verify.cpp create mode 100644 test/std/containers/views/span.cons/iterator_sentinel.pass.cpp create mode 100644 test/std/containers/views/span.cons/iterator_sentinel.verify.cpp delete mode 100644 test/std/containers/views/span.cons/ptr_len.fail.cpp delete mode 100644 test/std/containers/views/span.cons/ptr_len.pass.cpp delete mode 100644 test/std/containers/views/span.cons/ptr_ptr.fail.cpp delete mode 100644 test/std/containers/views/span.cons/ptr_ptr.pass.cpp create mode 100644 test/std/containers/views/span.cons/range.pass.cpp create mode 100644 test/std/containers/views/span.cons/span.dtor.compile.pass.cpp create mode 100644 test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/containers/views/span.obs/empty.nodiscard.verify.cpp create mode 100644 test/std/containers/views/span.sub/first.fail.cpp create mode 100644 test/std/containers/views/span.sub/last.fail.cpp create mode 100644 test/std/containers/views/span.sub/subspan.fail.cpp delete mode 100644 test/std/containers/views/span.tuple/get.fail.cpp delete mode 100644 test/std/containers/views/span.tuple/get.pass.cpp delete mode 100644 test/std/containers/views/span.tuple/tuple_element.fail.cpp delete mode 100644 test/std/containers/views/span.tuple/tuple_element.pass.cpp delete mode 100644 test/std/containers/views/span.tuple/tuple_size.fail.cpp delete mode 100644 test/std/containers/views/span.tuple/tuple_size.pass.cpp create mode 100644 test/std/containers/views/trivially_copyable.compile.pass.cpp create mode 100644 test/std/depr/depr.atomics/depr.atomics.nonmembers/atomic_init.depr_in_cxx20.verify.cpp rename test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.cons/{assignment.fail.cpp => assignment.compile.fail.cpp} (100%) rename test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.cons/{convert.fail.cpp => convert.compile.fail.cpp} (100%) rename test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.cons/{convert_assignment.fail.cpp => convert_assignment.compile.fail.cpp} (100%) rename test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.cons/{copy.fail.cpp => copy.compile.fail.cpp} (100%) rename test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.cons/{explicit.fail.cpp => explicit.compile.fail.cpp} (100%) delete mode 100644 test/std/depr/depr.auto.ptr/nothing_to_do.pass.cpp delete mode 100644 test/std/depr/depr.c.headers/stdint_h.sh.cpp create mode 100644 test/std/depr/depr.c.headers/stdlib_h.aligned_alloc.compile.pass.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/pointer_to_binary_function.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/pointer_to_binary_function.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/pointer_to_unary_function.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/pointer_to_unary_function.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/ptr_fun1.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/ptr_fun1.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/ptr_fun2.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.function.pointer.adaptors/ptr_fun2.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1_ref_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1_ref_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun1_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref1.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref1.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_ref_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/const_mem_fun_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1_ref_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1_ref_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun1_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref1.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref1.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_ref_t.cxx1z.fail.cpp create mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_t.cxx1z.compile.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/depr.member.pointer.adaptors/mem_fun_t.cxx1z.fail.cpp delete mode 100644 test/std/depr/depr.function.objects/depr.adaptors/nothing_to_do.pass.cpp delete mode 100644 test/std/depr/depr.function.objects/nothing_to_do.pass.cpp create mode 100644 test/std/depr/depr.ios.members/lit.local.cfg delete mode 100644 test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.fail.cpp create mode 100644 test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.verify.cpp delete mode 100644 test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.fail.cpp create mode 100644 test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.verify.cpp delete mode 100644 test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.fail.cpp create mode 100644 test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.verify.cpp delete mode 100644 test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.fail.cpp create mode 100644 test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.verify.cpp delete mode 100644 test/std/depr/depr.lib.binders/nothing_to_do.pass.cpp create mode 100644 test/std/depr/depr.str.strstreams/lit.local.cfg delete mode 100644 test/std/depr/exception.unexpected/nothing_to_do.pass.cpp delete mode 100644 test/std/depr/nothing_to_do.pass.cpp delete mode 100644 test/std/diagnostics/nothing_to_do.pass.cpp delete mode 100644 test/std/diagnostics/syserr/syserr.errcat/nothing_to_do.pass.cpp delete mode 100644 test/std/diagnostics/syserr/syserr.errcode/nothing_to_do.pass.cpp delete mode 100644 test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.fail.cpp delete mode 100644 test/std/diagnostics/syserr/syserr.errcondition/nothing_to_do.pass.cpp delete mode 100644 test/std/diagnostics/syserr/syserr.syserr/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/func/func.searchers/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/func/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/iterator/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp create mode 100644 test/std/experimental/memory/memory.resource/memory.resource.priv/private_members.fail.cpp delete mode 100644 test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp delete mode 100644 test/std/experimental/memory/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/nothing_to_do.pass.cpp delete mode 100644 test/std/experimental/utilities/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/file.streams/c.files/gets.compile.fail.cpp delete mode 100644 test/std/input.output/file.streams/c.files/gets.fail.cpp delete mode 100644 test/std/input.output/file.streams/fstreams/lit.local.cfg create mode 100644 test/std/input.output/file.streams/lit.local.cfg delete mode 100644 test/std/input.output/file.streams/nothing_to_do.pass.cpp delete mode 120000 test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink delete mode 100644 test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/file4 delete mode 120000 test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 delete mode 100644 test/std/input.output/filesystems/Inputs/static_test_env/dir1/file1 delete mode 100644 test/std/input.output/filesystems/Inputs/static_test_env/dir1/file2 delete mode 100644 test/std/input.output/filesystems/Inputs/static_test_env/empty_file delete mode 100644 test/std/input.output/filesystems/Inputs/static_test_env/non_empty_file delete mode 120000 test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir delete mode 120000 test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file create mode 100644 test/std/input.output/filesystems/class.directory_entry/directory_entry.io/directory_entry.io.pass.cpp create mode 100644 test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/input.output/filesystems/class.path/path.member/path.assign/braced_init.pass.cpp create mode 100644 test/std/input.output/filesystems/class.path/path.member/path.charconv.pass.cpp delete mode 100644 test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.fail.cpp create mode 100644 test/std/input.output/filesystems/class.path/path.member/path.decompose/empty.verify.cpp delete mode 100644 test/std/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp create mode 100644 test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/fs.filesystem.synopsis/enable_borrowed_range.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/fs.filesystem.synopsis/enable_view.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/fs.filesystem.synopsis/file_time_type_resolution.compile.pass.cpp create mode 100644 test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/toctou.pass.cpp delete mode 100644 test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp create mode 100644 test/std/input.output/input.output.general/lit.local.cfg delete mode 100644 test/std/input.output/iostream.format/input.streams/istream.formatted/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/iostream.format/input.streams/istream.rvalue/not_istreamable.verify.cpp create mode 100644 test/std/input.output/iostream.format/lit.local.cfg delete mode 100644 test/std/input.output/iostream.format/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/iostream.format/output.streams/ostream.formatted/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.volatile.pass.cpp delete mode 100644 test/std/input.output/iostream.format/output.streams/ostream.rvalue/CharT_pointer.pass.cpp create mode 100644 test/std/input.output/iostream.format/output.streams/ostream.rvalue/not_ostreamable.verify.cpp create mode 100644 test/std/input.output/iostream.format/output.streams/ostream.rvalue/rvalue.pass.cpp delete mode 100644 test/std/input.output/iostream.format/quoted.manip/quoted_char.fail.cpp create mode 100644 test/std/input.output/iostream.format/quoted.manip/quoted_char.verify.cpp delete mode 100644 test/std/input.output/iostream.format/quoted.manip/quoted_traits.fail.cpp create mode 100644 test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp create mode 100644 test/std/input.output/iostream.forward/lit.local.cfg create mode 100644 test/std/input.output/iostream.objects/check-stderr.sh create mode 100644 test/std/input.output/iostream.objects/check-stdout.sh create mode 100644 test/std/input.output/iostream.objects/init.pass.cpp create mode 100644 test/std/input.output/iostream.objects/lit.local.cfg delete mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cerr.pass.cpp create mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cerr.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cin.pass.cpp create mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cin.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/clog.pass.cpp create mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/clog.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cout.pass.cpp create mode 100644 test/std/input.output/iostream.objects/narrow.stream.objects/cout.sh.cpp create mode 100644 test/std/input.output/iostream.objects/send-stdin.sh delete mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcerr.pass.cpp create mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcerr.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcin.pass.cpp create mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcin.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wclog.pass.cpp create mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wclog.sh.cpp delete mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcout.pass.cpp create mode 100644 test/std/input.output/iostream.objects/wide.stream.objects/wcout.sh.cpp create mode 100644 test/std/input.output/iostreams.base/fpos/fpos.operations/fpos.pass.cpp delete mode 100644 test/std/input.output/iostreams.base/fpos/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/iostreams.base/ios.base/ios.types/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/iostreams.base/ios.base/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/iostreams.base/lit.local.cfg delete mode 100644 test/std/input.output/iostreams.base/std.ios.manip/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/iostreams.requirements/lit.local.cfg delete mode 100644 test/std/input.output/iostreams.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/stream.buffers/lit.local.cfg rename test/std/input.output/stream.buffers/streambuf/streambuf.cons/{default.fail.cpp => default.compile.fail.cpp} (100%) delete mode 100644 test/std/input.output/stream.buffers/streambuf/streambuf.members/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/stream.buffers/streambuf/streambuf.protected/nothing_to_do.pass.cpp delete mode 100644 test/std/input.output/stream.buffers/streambuf/streambuf.virtuals/nothing_to_do.pass.cpp create mode 100644 test/std/input.output/string.streams/lit.local.cfg delete mode 100644 test/std/iterators/iterator.container/empty.array.fail.cpp create mode 100644 test/std/iterators/iterator.container/empty.array.verify.cpp delete mode 100644 test/std/iterators/iterator.container/empty.container.fail.cpp create mode 100644 test/std/iterators/iterator.container/empty.container.verify.cpp delete mode 100644 test/std/iterators/iterator.container/empty.initializer_list.fail.cpp create mode 100644 test/std/iterators/iterator.container/empty.initializer_list.verify.cpp create mode 100644 test/std/iterators/iterator.primitives/iterator.basic/deprecated.verify.cpp create mode 100644 test/std/iterators/iterator.primitives/iterator.operations/robust_against_adl.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/iterator.traits/cxx20_iterator_traits.compile.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp delete mode 100644 test/std/iterators/iterator.primitives/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/constraints.verify.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/iterator_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/lwg3664.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.distance/range.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/constraints.compile.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/constraints.compile.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/iterator_count_sentinel.pass.cpp create mode 100644 test/std/iterators/iterator.primitives/range.iter.ops/types.h create mode 100644 test/std/iterators/iterator.primitives/std.iterator.tags/contiguous_iterator_tag.pass.cpp rename test/std/iterators/iterator.range/{begin-end.fail.cpp => begin-end.compile.fail.cpp} (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/begin_array.pass.cpp (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/begin_const.pass.cpp (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/begin_non_const.pass.cpp (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/end_array.pass.cpp (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/end_const.pass.cpp (100%) rename test/std/iterators/{stream.iterators => }/iterator.range/end_non_const.pass.cpp (100%) create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.move/indirectly_movable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.move/indirectly_movable.subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.move/indirectly_movable_storable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.move/indirectly_movable_storable.subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_result_t.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/incrementable_traits.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.assoc.types/incrementable.traits/iter_difference_t.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/indirectly_readable_traits.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/iter_value_t.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/incrementable.h create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.forward/forward_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.forward/subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.inc/incrementable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.inc/subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/input_or_output_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.output/output_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/iter_common_reference_t.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.subsumption.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sized_sentinel_for.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.winc/weakly_incrementable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.writable/indirectly_writable.compile.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.nodiscard.verify.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.swap/iter_swap.pass.cpp create mode 100644 test/std/iterators/iterator.requirements/iterator.cust/unqualified_lookup_wrapper.h delete mode 100644 test/std/iterators/iterator.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/iterators/iterators.general/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/arrow.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/assign.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/base.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/compare.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/count.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/ctor.conv.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/ctor.iter.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/decrement.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/deref.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/increment.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/iter_move.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/iter_swap.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/iterator_traits.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/member_types.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/minus.default_sentinel.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/minus.eq.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/minus.iter.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/minus.size.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/plus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/subscript.pass.cpp create mode 100644 test/std/iterators/predef.iterators/counted.iterator/three_way_compare.pass.cpp create mode 100644 test/std/iterators/predef.iterators/default.sentinel/default.sentinel.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/insert.iterator/cxx20_iter_member.pass.cpp create mode 100644 test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/insert.iterators/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/assign.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/constraints.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/ctor.converting.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/ctor.default.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/ctor.iter.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/ctor.sentinel.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/deref.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/eq.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/iter_move.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/iter_swap.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/minus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/plus_plus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/iterators.common/types.h delete mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/convert.fail.cpp create mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/ctor.convert.LWG3435.verify.cpp create mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/ctor.iter.explicit.verify.cpp delete mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/iter.fail.cpp create mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/assign.LWG3435.verify.cpp delete mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iter.ops/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/move.iterators/nothing_to_do.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/three-way.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.LWG3435.verify.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.explicit.verify.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.LWG3435.verify.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/nothing_to_do.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.cons/default.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.cons/iter.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.cons/iter.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.cons/reverse_iterator.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.cons/reverse_iterator.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.conv/tested_elsewhere.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.make/make_reverse_iterator.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op!=/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op++/post.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op++/pre.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op+/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op+=/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op--/post.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op--/pre.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op-/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op-=/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op.star/op_star.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op=/reverse_iterator.fail.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op=/reverse_iterator.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.op==/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opdiff/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opgt/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opgt=/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opindex/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.oplt/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.oplt=/test.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opref/op_arrow.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.ops/reverse.iter.opsum/difference_type.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp create mode 100644 test/std/iterators/predef.iterators/reverse.iterators/types.pass.cpp create mode 100644 test/std/iterators/predef.iterators/unreachable.sentinel/unreachable_sentinel.pass.cpp rename test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/{default.fail.cpp => default.compile.fail.cpp} (100%) create mode 100644 test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/iterators/stream.iterators/lit.local.cfg delete mode 100644 test/std/iterators/stream.iterators/nothing_to_do.pass.cpp create mode 100644 test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/partial_order.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/strong_order.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/strong_order_long_double.verify.cpp create mode 100644 test/std/language.support/cmp/cmp.alg/weak_order.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.categories.pre/zero_type.verify.cpp create mode 100644 test/std/language.support/cmp/cmp.concept/three_way_comparable.compile.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp create mode 100644 test/std/language.support/cmp/cmp.result/compare_three_way_result.compile.pass.cpp delete mode 100644 test/std/language.support/cmp/cmp.strongeq/cmp.strongeq.pass.cpp delete mode 100644 test/std/language.support/cmp/cmp.weakeq/cmp.weakeq.pass.cpp create mode 100644 test/std/language.support/cmp/compare.syn/named_functions.pass.cpp delete mode 100644 test/std/language.support/nothing_to_do.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.handle/void_handle.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.traits/promise_type.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.pass.cpp create mode 100644 test/std/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/await_result.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/bool_await_suspend.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/expected.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/fullexpr-dtor.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/generator.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/go.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/multishot_func.pass.cpp create mode 100644 test/std/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp delete mode 100644 test/std/language.support/support.dynamic/alloc.errors/nothing_to_do.pass.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.verify.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.pass.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array_ptr.fail.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array_ptr.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_ptr.fail.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_ptr.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.fail.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.sh.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.verify.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.fail.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.verify.cpp create mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.pass.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp delete mode 100644 test/std/language.support/support.dynamic/new.delete/nothing_to_do.pass.cpp delete mode 100644 test/std/language.support/support.dynamic/ptr.launder/launder.nodiscard.fail.cpp create mode 100644 test/std/language.support/support.dynamic/ptr.launder/launder.nodiscard.verify.cpp delete mode 100644 test/std/language.support/support.exception/exception.terminate/nothing_to_do.pass.cpp delete mode 100644 test/std/language.support/support.limits/nothing_to_do.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/barrier.version.pass.cpp delete mode 100644 test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/charconv.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/coroutine.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/format.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/latch.version.pass.cpp delete mode 100644 test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/numbers.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/queue.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/ranges.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/semaphore.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/span.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/stack.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/thread.version.pass.cpp create mode 100644 test/std/language.support/support.limits/support.limits.general/typeinfo.version.pass.cpp create mode 100644 test/std/language.support/support.runtime/cstdlib.aligned_alloc.compile.pass.cpp create mode 100644 test/std/language.support/support.runtime/ctime.timespec.compile.pass.cpp delete mode 100644 test/std/language.support/support.start.term/quick_exit_check1.fail.cpp delete mode 100644 test/std/language.support/support.start.term/quick_exit_check2.fail.cpp create mode 100644 test/std/language.support/support.types/byteops/lshift.assign.compile.fail.cpp delete mode 100644 test/std/language.support/support.types/byteops/lshift.assign.fail.cpp create mode 100644 test/std/language.support/support.types/byteops/lshift.compile.fail.cpp delete mode 100644 test/std/language.support/support.types/byteops/lshift.fail.cpp create mode 100644 test/std/language.support/support.types/byteops/rshift.assign.compile.fail.cpp delete mode 100644 test/std/language.support/support.types/byteops/rshift.assign.fail.cpp create mode 100644 test/std/language.support/support.types/byteops/rshift.compile.fail.cpp delete mode 100644 test/std/language.support/support.types/byteops/rshift.fail.cpp create mode 100644 test/std/language.support/support.types/byteops/to_integer.compile.fail.cpp delete mode 100644 test/std/language.support/support.types/byteops/to_integer.fail.cpp create mode 100644 test/std/language.support/support.types/max_align_t.compile.pass.cpp delete mode 100644 test/std/language.support/support.types/max_align_t.pass.cpp rename test/std/language.support/support.types/{nullptr_t_integral_cast.fail.cpp => nullptr_t_integral_cast.compile.fail.cpp} (100%) create mode 100644 test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp create mode 100644 test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp create mode 100644 test/std/library/description/conventions/expos.only.func/synth_three_way.pass.cpp create mode 100644 test/std/localization/lit.local.cfg delete mode 100644 test/std/localization/locale.categories/category.collate/nothing_to_do.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.statics/table_size.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/codecvt_byname_char16_t_char.depr_in_cxx20.verify.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/codecvt_byname_char32_t_char.depr_in_cxx20.verify.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_char16_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt.byname/ctor_char32_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/codecvt_char16_t_char.depr_in_cxx20.verify.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/codecvt_char32_t_char.depr_in_cxx20.verify.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char16_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/ctor_char32_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_always_noconv.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_encoding.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_in.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_length.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_max_length.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_out.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char16_t_char8_t_unshift.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_always_noconv.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_encoding.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_in.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_length.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_max_length.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_out.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/char32_t_char8_t_unshift.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char16_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/locale.codecvt/types_char32_t_char8_t.pass.cpp create mode 100644 test/std/localization/locale.categories/category.ctype/with_public_dtor.hpp delete mode 100644 test/std/localization/locale.categories/category.messages/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locale.categories/category.monetary/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locale.categories/category.numeric/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locale.categories/category.time/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locale.categories/facet.numpunct/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locales/locale.convenience/conversions/conversions.buffer/lit.local.cfg delete mode 100644 test/std/localization/locales/locale.convenience/conversions/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locales/locale.convenience/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locales/locale/locale.types/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locales/locale/nothing_to_do.pass.cpp delete mode 100644 test/std/localization/locales/nothing_to_do.pass.cpp create mode 100644 test/std/namespace/addressable_functions.sh.cpp delete mode 100644 test/std/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/bit/bit.cast/bit_cast.compile.pass.cpp create mode 100644 test/std/numerics/bit/bit.cast/bit_cast.pass.cpp create mode 100644 test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp create mode 100644 test/std/numerics/bit/bit.pow.two/bit_ceil.pass.cpp create mode 100644 test/std/numerics/bit/bit.pow.two/bit_floor.pass.cpp create mode 100644 test/std/numerics/bit/bit.pow.two/bit_width.pass.cpp delete mode 100644 test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp delete mode 100644 test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp delete mode 100644 test/std/numerics/bit/bit.pow.two/floor2.pass.cpp create mode 100644 test/std/numerics/bit/bit.pow.two/has_single_bit.pass.cpp delete mode 100644 test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp delete mode 100644 test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp create mode 100644 test/std/numerics/bit/byteswap.pass.cpp delete mode 100644 test/std/numerics/bit/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/c.math/abs.fail.cpp create mode 100644 test/std/numerics/c.math/abs.verify.cpp delete mode 100644 test/std/numerics/c.math/c.math.lerp/c.math.lerp.pass.cpp create mode 100644 test/std/numerics/c.math/lerp.pass.cpp create mode 100644 test/std/numerics/complex.number/complex.literals/literals1.compile.fail.cpp delete mode 100644 test/std/numerics/complex.number/complex.literals/literals1.fail.cpp rename test/std/numerics/complex.number/complex.special/{double_long_double_implicit.fail.cpp => double_long_double_implicit.compile.fail.cpp} (100%) rename test/std/numerics/complex.number/complex.special/{float_double_implicit.fail.cpp => float_double_implicit.compile.fail.cpp} (100%) rename test/std/numerics/complex.number/complex.special/{float_long_double_implicit.fail.cpp => float_long_double_implicit.compile.fail.cpp} (100%) delete mode 100644 test/std/numerics/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/numarray/class.gslice/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/numarray/class.slice/nothing_to_do.pass.cpp rename test/std/numerics/numarray/template.gslice.array/{default.fail.cpp => default.compile.fail.cpp} (100%) rename test/std/numerics/numarray/template.indirect.array/{default.fail.cpp => default.compile.fail.cpp} (100%) rename test/std/numerics/numarray/template.mask.array/{default.fail.cpp => default.compile.fail.cpp} (100%) rename test/std/numerics/numarray/template.slice.array/{default.fail.cpp => default.compile.fail.cpp} (100%) create mode 100644 test/std/numerics/numarray/template.slice.array/slice.arr.assign/template.pass.cpp create mode 100644 test/std/numerics/numarray/template.valarray/valarray.assign/value_assign.addressof.compile.pass.cpp create mode 100644 test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp delete mode 100644 test/std/numerics/numarray/valarray.nonmembers/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/valarray_helper.h create mode 100644 test/std/numerics/numbers/defined.pass.cpp create mode 100644 test/std/numerics/numbers/illformed.verify.cpp create mode 100644 test/std/numerics/numbers/specialize.pass.cpp create mode 100644 test/std/numerics/numbers/user_type.pass.cpp create mode 100644 test/std/numerics/numbers/value.pass.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool1.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool1.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool2.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool2.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool3.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool3.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool4.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.bool4.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.not_integral1.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.not_integral1.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.not_integral2.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.not_integral2.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool1.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool1.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool2.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool2.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool3.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool3.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool4.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.bool4.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.not_integral1.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.not_integral1.fail.cpp create mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.not_integral2.compile.fail.cpp delete mode 100644 test/std/numerics/numeric.ops/numeric.ops.lcm/lcm.not_integral2.fail.cpp delete mode 100644 test/std/numerics/rand/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.adapt/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.bern/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.PR44847.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.norm/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.pois/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.samp/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.uni/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/int128.pass.cpp delete mode 100644 test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_int_int.pass.cpp create mode 100644 test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_real_real.pass.cpp delete mode 100644 test/std/numerics/rand/rand.eng/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/rand/rand.eng/rand.eng.lcong/alg.pass.cpp create mode 100644 test/std/numerics/rand/rand.eng/rand.eng.lcong/params.fail.cpp delete mode 100644 test/std/numerics/rand/rand.req/nothing_to_do.pass.cpp delete mode 100644 test/std/numerics/rand/rand.req/rand.req.urng/nothing_to_do.pass.cpp create mode 100644 test/std/numerics/rand/rand.req/rand.req.urng/uniform_random_bit_generator.compile.pass.cpp delete mode 100644 test/std/numerics/rand/rand.util/nothing_to_do.pass.cpp rename test/std/numerics/rand/rand.util/rand.util.seedseq/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/numerics/rand/rand.util/rand.util.seedseq/{copy.fail.cpp => copy.compile.fail.cpp} (100%) create mode 100644 test/std/numerics/rand/rand.util/rand.util.seedseq/iterator.verify.cpp create mode 100644 test/std/ranges/range.access/begin.pass.cpp create mode 100644 test/std/ranges/range.access/data.pass.cpp create mode 100644 test/std/ranges/range.access/empty.pass.cpp create mode 100644 test/std/ranges/range.access/end.pass.cpp create mode 100644 test/std/ranges/range.access/size.pass.cpp create mode 100644 test/std/ranges/range.access/ssize.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/all.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/all_t.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/begin_end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/constructor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/data.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/empty.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.owning.view/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.ref.view/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.all/range.ref.view/range.ref.view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/adaptor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/ctor.view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.common.view/types.h create mode 100644 test/std/ranges/range.adaptors/range.counted/counted.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/ctor.view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/dangling.cache.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/general.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.drop/types.h create mode 100644 test/std/ranges/range.adaptors/range.empty/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.empty/empty_view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/ctad.verify.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/ctor.view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/general.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/arrow.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/ctor.other.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/ctor.parent.outer.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/decrement.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/eq.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/increment.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/iter.move.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/iter.swap.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/iterator/star.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/sentinel/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/sentinel/ctor.other.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/sentinel/ctor.parent.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/sentinel/eq.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.join.view/types.h create mode 100644 test/std/ranges/range.adaptors/range.reverse/adaptor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/ctor.view.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.reverse/types.h create mode 100644 test/std/ranges/range.adaptors/range.take/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/ctor.view_count.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/sentinel/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/sentinel/ctor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/sentinel/eq.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.take/types.h create mode 100644 test/std/ranges/range.adaptors/range.transform/adaptor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/begin.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/ctor.view_function.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/end.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/general.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/arithmetic.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/base.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/compare.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/ctor.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/deref.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/iter_move.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/plus_minus.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/requirements.compile.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/sentinel.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/subscript.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/size.pass.cpp create mode 100644 test/std/ranges/range.adaptors/range.transform/types.h create mode 100644 test/std/ranges/range.factories/range.iota.view/begin.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/ctor.first.last.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/ctor.value.bound.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/ctor.value.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/end.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/compare.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/ctor.value.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/decrement.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/increment.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/minus.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/minus_eq.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/plus.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/plus_eq.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/iterator/subscript.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/sentinel/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/sentinel/ctor.value.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/sentinel/eq.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/sentinel/minus.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/size.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/type.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.iota.view/types.h create mode 100644 test/std/ranges/range.factories/range.iota.view/views_iota.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/assign.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/begin.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/ctor.in_place.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/ctor.value.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/data.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/end.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/range_concept_conformance.compile.pass.cpp create mode 100644 test/std/ranges/range.factories/range.single.view/size.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/borrowed_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/borrowed_range.subsumption.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/enable_borrowed_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/helper_aliases.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/iterator_t.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/bidirectional_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/forward_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/output_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/random_access_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.sized/sized_range.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.sized/subsumption.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.view/view.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.view/view.subsumption.compile.pass.cpp create mode 100644 test/std/ranges/range.req/range.view/view_base.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.dangling/borrowed_iterator.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.dangling/borrowed_subrange.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.dangling/dangling.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/advance.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/borrowing.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctad.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.begin_end.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.begin_end_size.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.default.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.pair_like_conv.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.range.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/ctor.range_size.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/general.compile.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/get.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/lwg3470.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/primitives.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/structured_bindings.pass.cpp create mode 100644 test/std/ranges/range.utility/range.subrange/types.h create mode 100644 test/std/ranges/range.utility/view.interface/view.interface.pass.cpp create mode 100644 test/std/re/lit.local.cfg delete mode 100644 test/std/re/nothing_to_do.pass.cpp delete mode 100644 test/std/re/re.alg/nothing_to_do.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.match/awk.locale.pass.cpp rename test/std/re/re.alg/re.alg.match/{basic.fail.cpp => basic.compile.fail.cpp} (100%) create mode 100644 test/std/re/re.alg/re.alg.match/basic.locale.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.match/ecma.locale.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.match/extended.locale.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.search/awk.locale.pass.cpp rename test/std/re/re.alg/re.alg.search/{basic.fail.cpp => basic.compile.fail.cpp} (100%) create mode 100644 test/std/re/re.alg/re.alg.search/basic.locale.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.search/ecma.locale.pass.cpp create mode 100644 test/std/re/re.alg/re.alg.search/extended.locale.pass.cpp delete mode 100644 test/std/re/re.const/nothing_to_do.pass.cpp create mode 100644 test/std/re/re.const/re.matchflag/match_multiline.pass.cpp create mode 100644 test/std/re/re.const/re.matchflag/match_prev_avail.pass.cpp delete mode 100644 test/std/re/re.def/nothing_to_do.pass.cpp delete mode 100644 test/std/re/re.grammar/nothing_to_do.pass.cpp delete mode 100644 test/std/re/re.iter/nothing_to_do.pass.cpp create mode 100644 test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp rename test/std/re/re.iter/re.regiter/re.regiter.cnstr/{cnstr.fail.cpp => cnstr.compile.fail.cpp} (100%) create mode 100644 test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp rename test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/{array.fail.cpp => array.compile.fail.cpp} (100%) rename test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/{init.fail.cpp => init.compile.fail.cpp} (100%) rename test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/{int.fail.cpp => int.compile.fail.cpp} (100%) rename test/std/re/re.iter/re.tokiter/re.tokiter.cnstr/{vector.fail.cpp => vector.compile.fail.cpp} (100%) delete mode 100644 test/std/re/re.regex/re.regex.nonmemb/nothing_to_do.pass.cpp create mode 100644 test/std/re/re.results/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/re/re.results/re.results.size/empty.fail.cpp create mode 100644 test/std/re/re.results/re.results.size/empty.verify.cpp create mode 100644 test/std/strings/basic.string.literals/literal.verify.cpp delete mode 100644 test/std/strings/basic.string.literals/literal1.fail.cpp delete mode 100644 test/std/strings/basic.string.literals/literal1.pass.cpp delete mode 100644 test/std/strings/basic.string.literals/literal2.fail.cpp delete mode 100644 test/std/strings/basic.string.literals/literal2.pass.cpp delete mode 100644 test/std/strings/basic.string.literals/literal3.pass.cpp rename test/std/strings/basic.string/{allocator_mismatch.fail.cpp => allocator_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/strings/basic.string/cpp17_input_iterator.h delete mode 100644 test/std/strings/basic.string/input_iterator.h create mode 100644 test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_back.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_cback.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_cfront.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_cindex.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_front.pass.cpp delete mode 100644 test/std/strings/basic.string/string.access/db_index.pass.cpp delete mode 100644 test/std/strings/basic.string/string.capacity/empty.fail.cpp create mode 100644 test/std/strings/basic.string/string.capacity/empty.verify.cpp create mode 100644 test/std/strings/basic.string/string.capacity/reserve.deprecated_in_cxx20.verify.cpp create mode 100644 test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp create mode 100644 test/std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp create mode 100644 test/std/strings/basic.string/string.capacity/shrink_to_fit.explicit_instantiation.sh.cpp create mode 100644 test/std/strings/basic.string/string.cons/nullptr.compile.pass.cpp rename test/std/strings/basic.string/string.cons/{string_view.fail.cpp => string_view.compile.fail.cpp} (100%) create mode 100644 test/std/strings/basic.string/string.contains/contains.char.pass.cpp create mode 100644 test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp create mode 100644 test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_2.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_3.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_4.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_5.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_6.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_7.pass.cpp delete mode 100644 test/std/strings/basic.string/string.iterators/db_iterators_8.pass.cpp create mode 100644 test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/strings/basic.string/string.modifiers/nothing_to_do.pass.cpp create mode 100644 test/std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp delete mode 100644 test/std/strings/basic.string/string.nonmembers/nothing_to_do.pass.cpp create mode 100644 test/std/strings/basic.string/string.nonmembers/string.io/lit.local.cfg delete mode 100644 test/std/strings/basic.string/string.ops/nothing_to_do.pass.cpp rename test/std/strings/basic.string/{traits_mismatch.fail.cpp => traits_mismatch.compile.fail.cpp} (100%) delete mode 100644 test/std/strings/char.traits/char.traits.specializations/nothing_to_do.pass.cpp delete mode 100644 test/std/strings/char.traits/nothing_to_do.pass.cpp create mode 100644 test/std/strings/string.view/enable_borrowed_range.compile.pass.cpp create mode 100644 test/std/strings/string.view/range_concept_conformance.compile.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.capacity/empty.fail.cpp create mode 100644 test/std/strings/string.view/string.view.capacity/empty.verify.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/equal.pass.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/greater.pass.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/greater_equal.pass.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/less.pass.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/less_equal.pass.cpp create mode 100644 test/std/strings/string.view/string.view.comparison/not_equal.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opeq.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opge.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opge.string_view.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opgt.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opgt.string_view.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/ople.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/ople.string_view.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/oplt.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/oplt.string_view.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opne.string_view.string.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.comparison/opne.string_view.string_view.pass.cpp create mode 100644 test/std/strings/string.view/string.view.cons/from_iterator_sentinel.pass.cpp create mode 100644 test/std/strings/string.view/string.view.cons/from_range.pass.cpp create mode 100644 test/std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp delete mode 100644 test/std/strings/string.view/string.view.cons/from_string1.fail.cpp create mode 100644 test/std/strings/string.view/string.view.cons/from_string2.compile.fail.cpp delete mode 100644 test/std/strings/string.view/string.view.cons/from_string2.fail.cpp create mode 100644 test/std/strings/string.view/string.view.cons/nullptr.compile.pass.cpp create mode 100644 test/std/strings/string.view/string.view.deduct/iterator_sentinel.pass.cpp create mode 100644 test/std/strings/string.view/string.view.deduct/range.pass.cpp create mode 100644 test/std/strings/string.view/string.view.io/stream_insert_decl_present.compile.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.io/stream_insert_decl_present.pass.cpp create mode 100644 test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/contains.char.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/contains.ptr.pass.cpp create mode 100644 test/std/strings/string.view/string.view.template/contains.string_view.pass.cpp delete mode 100644 test/std/strings/string.view/string.view.template/nothing_to_do.pass.cpp create mode 100644 test/std/strings/string.view/string_view.literals/literal.verify.cpp delete mode 100644 test/std/strings/string.view/string_view.literals/literal1.fail.cpp delete mode 100644 test/std/strings/string.view/string_view.literals/literal1.pass.cpp delete mode 100644 test/std/strings/string.view/string_view.literals/literal2.fail.cpp delete mode 100644 test/std/strings/string.view/string_view.literals/literal2.pass.cpp delete mode 100644 test/std/strings/string.view/string_view.literals/literal3.pass.cpp rename test/std/strings/string.view/{traits_mismatch.fail.cpp => traits_mismatch.compile.fail.cpp} (100%) create mode 100644 test/std/strings/string.view/trivially_copyable.compile.pass.cpp delete mode 100644 test/std/thread/futures/futures.async/async.fail.cpp create mode 100644 test/std/thread/futures/futures.async/async.verify.cpp delete mode 100644 test/std/thread/futures/futures.promise/copy_assign.fail.cpp create mode 100644 test/std/thread/futures/futures.promise/copy_assign.verify.cpp delete mode 100644 test/std/thread/futures/futures.promise/copy_ctor.fail.cpp create mode 100644 test/std/thread/futures/futures.promise/copy_ctor.verify.cpp create mode 100644 test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.compile.pass.cpp delete mode 100644 test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.pass.cpp delete mode 100644 test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp create mode 100644 test/std/thread/futures/futures.unique_future/copy_assign.verify.cpp delete mode 100644 test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp create mode 100644 test/std/thread/futures/futures.unique_future/copy_ctor.verify.cpp create mode 100644 test/std/thread/thread.barrier/arrive.pass.cpp create mode 100644 test/std/thread/thread.barrier/arrive_and_drop.pass.cpp create mode 100644 test/std/thread/thread.barrier/arrive_and_wait.pass.cpp create mode 100644 test/std/thread/thread.barrier/completion.pass.cpp create mode 100644 test/std/thread/thread.barrier/max.pass.cpp rename test/std/thread/thread.condition/thread.condition.condvar/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.condition/thread.condition.condvar/{copy.fail.cpp => copy.compile.fail.cpp} (100%) rename test/std/thread/thread.condition/thread.condition.condvarany/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.condition/thread.condition.condvarany/{copy.fail.cpp => copy.compile.fail.cpp} (100%) create mode 100644 test/std/thread/thread.latch/arrive_and_wait.pass.cpp create mode 100644 test/std/thread/thread.latch/count_down.pass.cpp create mode 100644 test/std/thread/thread.latch/max.pass.cpp create mode 100644 test/std/thread/thread.latch/try_wait.pass.cpp rename test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.lock/thread.lock.guard/{copy.fail.cpp => copy.compile.fail.cpp} (100%) create mode 100644 test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp create mode 100644 test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp rename test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/{copy_assign.fail.cpp => copy_assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/{copy_ctor.fail.cpp => copy_ctor.compile.fail.cpp} (100%) delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/{copy.fail.cpp => copy.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/{copy.fail.cpp => copy.compile.fail.cpp} (100%) delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/lit.local.cfg delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/lit.local.cfg delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp create mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp create mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/{copy.fail.cpp => copy.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/{assign.fail.cpp => assign.compile.fail.cpp} (100%) rename test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/{copy.fail.cpp => copy.compile.fail.cpp} (100%) delete mode 100644 test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp create mode 100644 test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp create mode 100644 test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.compile.fail.cpp delete mode 100644 test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp delete mode 100644 test/std/thread/thread.req/nothing_to_do.pass.cpp delete mode 100644 test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp create mode 100644 test/std/thread/thread.semaphore/acquire.pass.cpp create mode 100644 test/std/thread/thread.semaphore/binary.pass.cpp create mode 100644 test/std/thread/thread.semaphore/ctor.compile.pass.cpp create mode 100644 test/std/thread/thread.semaphore/max.pass.cpp create mode 100644 test/std/thread/thread.semaphore/release.pass.cpp create mode 100644 test/std/thread/thread.semaphore/timed.pass.cpp create mode 100644 test/std/thread/thread.semaphore/try_acquire.pass.cpp create mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.compile.fail.cpp delete mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp create mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.compile.fail.cpp delete mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp create mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.compile.fail.cpp delete mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp create mode 100644 test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp create mode 100644 test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/deduct.pass.cpp delete mode 100644 test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.fail.cpp create mode 100644 test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.verify.cpp delete mode 100644 test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.fail.cpp create mode 100644 test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.verify.cpp delete mode 100644 test/std/utilities/any/any.class/not_literal_type.pass.cpp delete mode 100644 test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp create mode 100644 test/std/utilities/any/any.nonmembers/any.cast/const_correctness.verify.cpp delete mode 100644 test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp create mode 100644 test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.verify.cpp create mode 100644 test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_fixed_precision_to_chars_test_cases_1.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_fixed_precision_to_chars_test_cases_2.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_fixed_precision_to_chars_test_cases_3.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_fixed_precision_to_chars_test_cases_4.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_from_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_general_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_hex_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_scientific_precision_to_chars_test_cases_1.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_scientific_precision_to_chars_test_cases_2.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_scientific_precision_to_chars_test_cases_3.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_scientific_precision_to_chars_test_cases_4.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/double_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_fixed_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_from_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_general_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_hex_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_scientific_precision_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/float_to_chars_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/floating_point_test_cases.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/test.cpp create mode 100644 test/std/utilities/charconv/charconv.msvc/test.hpp create mode 100644 test/std/utilities/charconv/charconv.msvc/test.pass.cpp create mode 100644 test/std/utilities/charconv/charconv.syn/chars_format.pass.cpp create mode 100644 test/std/utilities/charconv/charconv.syn/from_chars_result.pass.cpp create mode 100644 test/std/utilities/charconv/charconv.syn/to_chars_result.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg.store/class.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg/ctor.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.arg/operator_bool.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp create mode 100644 test/std/utilities/format/format.arguments/format.args/types.compile.pass.cpp create mode 100644 test/std/utilities/format/format.error/format.error.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/format.context/advance_to.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/format.context/out.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.context/types.compile.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/advance_to.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/begin.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/check_arg_id.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/check_arg_id.verify.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/ctor.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/end.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp create mode 100644 test/std/utilities/format/format.formatter/format.parse.ctx/types.compile.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format_tests.h create mode 100644 test/std/utilities/format/format.functions/format_to.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format_to.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format_to_n.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/format_to_n.pass.cpp create mode 100644 test/std/utilities/format/format.functions/formatted_size.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/formatted_size.pass.cpp create mode 100644 test/std/utilities/format/format.functions/locale-specific_form.pass.cpp create mode 100644 test/std/utilities/format/format.functions/vformat.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/vformat.pass.cpp create mode 100644 test/std/utilities/format/format.functions/vformat_to.locale.pass.cpp create mode 100644 test/std/utilities/format/format.functions/vformat_to.pass.cpp create mode 100644 test/std/utilities/format/format.syn/format_to_n_result.pass.cpp delete mode 100644 test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp create mode 100644 test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/specialization.pass.cpp create mode 100644 test/std/utilities/function.objects/bind/func.bind/func.bind.isplace/is_placeholder.pass.cpp create mode 100644 test/std/utilities/function.objects/bind/func.bind/func.bind.isplace/specialization.pass.cpp delete mode 100644 test/std/utilities/function.objects/bind/func.bind/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/function.objects/bind/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/function.objects/comparisons/compare_three_way.pass.cpp create mode 100644 test/std/utilities/function.objects/comparisons/compare_three_way_functional.pass.cpp delete mode 100644 test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.h create mode 100644 test/std/utilities/function.objects/comparisons/transparent_three_way.compile.pass.cpp create mode 100644 test/std/utilities/function.objects/func.bind_front/bind_front.pass.cpp create mode 100644 test/std/utilities/function.objects/func.bind_front/bind_front.verify.cpp create mode 100644 test/std/utilities/function.objects/func.identity/identity.pass.cpp create mode 100644 test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp create mode 100644 test/std/utilities/function.objects/func.memfn/member_data.compile.fail.cpp delete mode 100644 test/std/utilities/function.objects/func.memfn/member_data.fail.cpp create mode 100644 test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp delete mode 100644 test/std/utilities/function.objects/func.search/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/addressof.pass.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.compile.fail.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.fail.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.fail.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.verify.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.fail.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.verify.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.fail.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.verify.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.fail.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.verify.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.fail.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.verify.cpp rename test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/{invoke.fail.cpp => invoke.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/noncopyable_return_type.pass.cpp create mode 100644 test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp delete mode 100644 test/std/utilities/function.objects/func.wrap/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.fail.cpp create mode 100644 test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.verify.cpp delete mode 100644 test/std/utilities/function.objects/negators/not1.depr_in_cxx17.fail.cpp create mode 100644 test/std/utilities/function.objects/negators/not1.depr_in_cxx17.verify.cpp delete mode 100644 test/std/utilities/function.objects/negators/not2.depr_in_cxx17.fail.cpp create mode 100644 test/std/utilities/function.objects/negators/not2.depr_in_cxx17.verify.cpp delete mode 100644 test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.fail.cpp create mode 100644 test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.verify.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/equal_to.pass.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/greater.pass.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/greater_equal.pass.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/less.pass.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/less_equal.pass.cpp create mode 100644 test/std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp delete mode 100644 test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.helpers/lwg3146.pass.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp delete mode 100644 test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp rename test/std/utilities/function.objects/refwrap/refwrap.invoke/{invoke.fail.cpp => invoke.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.incomplete.compile.fail.cpp delete mode 100644 test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.incomplete.fail.cpp create mode 100644 test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp rename test/std/utilities/function.objects/unord.hash/{enum.fail.cpp => enum.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/intseq/intseq.intseq/integer_seq.compile.fail.cpp delete mode 100644 test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp create mode 100644 test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.compile.fail.cpp delete mode 100644 test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp delete mode 100644 test/std/utilities/intseq/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.fail.cpp create mode 100644 test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.verify.cpp delete mode 100644 test/std/utilities/memory/allocator.uses/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/memory/default.allocator/PR50299.compile.pass.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp delete mode 100644 test/std/utilities/memory/default.allocator/allocator.members/address.pass.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator.members/allocate.constexpr.size.verify.cpp delete mode 100644 test/std/utilities/memory/default.allocator/allocator.members/allocate.fail.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator.members/allocate.verify.cpp delete mode 100644 test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp delete mode 100644 test/std/utilities/memory/default.allocator/allocator.members/max_size.pass.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator_types.removed_in_cxx20.verify.cpp create mode 100644 test/std/utilities/memory/default.allocator/allocator_types.void.compile.pass.cpp delete mode 100644 test/std/utilities/memory/default.allocator/allocator_void.pass.cpp create mode 100644 test/std/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.cpp create mode 100644 test/std/utilities/memory/pointer.conversion/to_address_on_function.verify.cpp create mode 100644 test/std/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/buffer.h create mode 100644 test/std/utilities/memory/specialized.algorithms/counted.h delete mode 100644 test/std/utilities/memory/specialized.algorithms/nothing_to_do.pass.cpp rename test/std/utilities/memory/specialized.algorithms/specialized.addressof/{addressof.temp.fail.cpp => addressof.temp.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/specialized.construct/ranges_construct_at.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/specialized.destroy/ranges_destroy.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/specialized.destroy/ranges_destroy_at.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/specialized.destroy/ranges_destroy_n.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/ranges_uninitialized_default_construct.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/ranges_uninitialized_default_construct_n.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp create mode 100644 test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp create mode 100644 test/std/utilities/memory/storage.iterator/deprecated.verify.cpp create mode 100644 test/std/utilities/memory/storage.iterator/types.compile.pass.cpp create mode 100644 test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp delete mode 100644 test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp delete mode 100644 test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp delete mode 100644 test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp delete mode 100644 test/std/utilities/memory/util.smartptr/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_copy_move.fail.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_construct.pass.cpp rename test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/{make_shared.private.fail.cpp => make_shared.private.compile.fail.cpp} (100%) delete mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp delete mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_arrow.fail.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bracket.fail.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bracket.pass.cpp create mode 100644 test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_deduction.pass.cpp rename test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/{not_less_than.fail.cpp => not_less_than.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.compile.fail.cpp delete mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.fail.cpp create mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/common_reference.compile.pass.cpp rename test/std/utilities/meta/meta.trans/meta.trans.other/{enable_if.fail.cpp => enable_if.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.compile.fail.cpp delete mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp create mode 100644 test/std/utilities/meta/meta.trans/meta.trans.other/result_of.deprecated.verify.cpp delete mode 100644 test/std/utilities/meta/meta.trans/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp create mode 100644 test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp create mode 100644 test/std/utilities/meta/meta.unary/meta.unary.prop/is_scoped_enum.pass.cpp delete mode 100644 test/std/utilities/meta/meta.unary/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/optional/iterator_concept_conformance.compile.pass.cpp create mode 100644 test/std/utilities/optional/optional.monadic/and_then.pass.cpp create mode 100644 test/std/utilities/optional/optional.monadic/or_else.pass.cpp create mode 100644 test/std/utilities/optional/optional.monadic/transform.pass.cpp create mode 100644 test/std/utilities/optional/optional.nullopt/nullopt_t.compile.fail.cpp delete mode 100644 test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp create mode 100644 test/std/utilities/optional/optional.object/optional.object.observe/value_const.compile.fail.cpp delete mode 100644 test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp rename test/std/utilities/ratio/ratio.arithmetic/{ratio_add.fail.cpp => ratio_add.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.arithmetic/{ratio_divide.fail.cpp => ratio_divide.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.arithmetic/{ratio_multiply.fail.cpp => ratio_multiply.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.arithmetic/{ratio_subtract.fail.cpp => ratio_subtract.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.ratio/{ratio1.fail.cpp => ratio1.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.ratio/{ratio2.fail.cpp => ratio2.compile.fail.cpp} (100%) rename test/std/utilities/ratio/ratio.ratio/{ratio3.fail.cpp => ratio3.compile.fail.cpp} (100%) delete mode 100644 test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp delete mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp create mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp delete mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp create mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.verify.cpp rename test/std/utilities/smartptr/unique.ptr/unique.ptr.create/{make_unique.array1.fail.cpp => make_unique.array1.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.create/{make_unique.array2.fail.cpp => make_unique.array2.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.create/{make_unique.array3.fail.cpp => make_unique.array3.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.create/{make_unique.array4.fail.cpp => make_unique.array4.compile.fail.cpp} (100%) delete mode 100644 test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp rename test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/{incomplete.fail.cpp => incomplete.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/{void.fail.cpp => void.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/{convert_ctor.fail.cpp => convert_ctor.compile.fail.cpp} (100%) rename test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/{incomplete.fail.cpp => incomplete.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp create mode 100644 test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp create mode 100644 test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp create mode 100644 test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp create mode 100644 test/std/utilities/template.bitset/bitset_test_cases.h delete mode 100644 test/std/utilities/time/date.time/ctime.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/nothing_to_do.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp delete mode 100644 test/std/utilities/time/time.clock/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp rename test/std/utilities/time/time.duration/{duration.fail.cpp => duration.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/{positive_num.fail.cpp => positive_num.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/{ratio.fail.cpp => ratio.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.alg/{abs.fail.cpp => abs.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cast/{ceil.fail.cpp => ceil.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cast/{floor.fail.cpp => floor.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cast/{round.fail.cpp => round.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cast/{toduration.fail.cpp => toduration.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cons/{convert_float_to_int.fail.cpp => convert_float_to_int.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cons/{convert_inexact.fail.cpp => convert_inexact.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cons/{rep01.fail.cpp => rep01.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cons/{rep02.fail.cpp => rep02.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.cons/{rep03.fail.cpp => rep03.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/time/time.duration/time.duration.literals/literals1.compile.fail.cpp delete mode 100644 test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp create mode 100644 test/std/utilities/time/time.duration/time.duration.literals/literals2.compile.fail.cpp delete mode 100644 test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp rename test/std/utilities/time/time.duration/time.duration.nonmember/{op_divide_rep.fail.cpp => op_divide_rep.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.nonmember/{op_mod_rep.fail.cpp => op_mod_rep.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.nonmember/{op_times_rep1.fail.cpp => op_times_rep1.compile.fail.cpp} (100%) rename test/std/utilities/time/time.duration/time.duration.nonmember/{op_times_rep2.fail.cpp => op_times_rep2.compile.fail.cpp} (100%) delete mode 100644 test/std/utilities/time/time.hms/time.hms.members/precision_type.pass.cpp rename test/std/utilities/time/time.point/{duration.fail.cpp => duration.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cast/{ceil.fail.cpp => ceil.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cast/{floor.fail.cpp => floor.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cast/{round.fail.cpp => round.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cast/{toduration.fail.cpp => toduration.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.comparisons/{op_equal.fail.cpp => op_equal.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.comparisons/{op_less.fail.cpp => op_less.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cons/{convert.fail.cpp => convert.compile.fail.cpp} (100%) rename test/std/utilities/time/time.point/time.point.cons/{duration.fail.cpp => duration.compile.fail.cpp} (100%) delete mode 100644 test/std/utilities/time/time.traits/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/PR27375.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/PR38601.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.compile.fail.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.fail.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.assign/derived_from_tuple_like.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.assign/laziness.pass.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.compile.fail.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.fail.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/cnstr_with_any.compile.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types2.compile.fail.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types2.fail.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.compile.fail.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.fail.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/default.lazy.verify.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/empty_tuple_trivial.compile.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/recursion_depth.pass.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.compile.fail.cpp delete mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.fail.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_three_way.compile.pass.cpp create mode 100644 test/std/utilities/tuple/tuple.tuple/tuple.rel/three_way.pass.cpp delete mode 100644 test/std/utilities/utility.requirements/nothing_to_do.pass.cpp create mode 100644 test/std/utilities/utility/as_const/as_const.compile.fail.cpp delete mode 100644 test/std/utilities/utility/as_const/as_const.fail.cpp delete mode 100644 test/std/utilities/utility/pairs/nothing_to_do.pass.cpp rename test/std/utilities/utility/pairs/pair.astuple/{get_const.fail.cpp => get_const.compile.fail.cpp} (100%) create mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.compile.fail.cpp delete mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp create mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.compile.fail.cpp delete mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp create mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.compile.fail.cpp delete mode 100644 test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp create mode 100644 test/std/utilities/utility/pairs/pairs.pair/ctor.brace-init.P1951.pass.cpp create mode 100644 test/std/utilities/utility/pairs/pairs.pair/ctor.brace-init.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_equal/cmp_equal.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater_equal/cmp_greater_equal.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.cmp_not_equal/cmp_not_equal.pass.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.fail.cpp create mode 100644 test/std/utilities/utility/utility.intcmp/intcmp.in_range/in_range.pass.cpp create mode 100644 test/std/utilities/utility/utility.underlying/to_underlying.pass.cpp create mode 100644 test/std/utilities/utility/utility.underlying/to_underlying.verify.cpp create mode 100644 test/std/utilities/variant/variant.visit/robust_against_adl.pass.cpp create mode 100644 test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp delete mode 100644 test/support/assert_checkpoint.h create mode 100644 test/support/atomic_helpers.h create mode 100644 test/support/callable_types.h create mode 100644 test/support/compare_types.h delete mode 100644 test/support/coroutine_types.h create mode 100644 test/support/debug_macros.h create mode 100644 test/support/deduction_guides_sfinae_checks.h delete mode 100644 test/support/demangle.h delete mode 100644 test/support/disable_missing_braces_warning.h delete mode 100644 test/support/filesystem_dynamic_test_helper.py create mode 100644 test/support/indirectly_readable.h create mode 100644 test/support/iterator_traits_cpp17_iterators.h create mode 100644 test/support/make_implicit.h create mode 100644 test/support/make_string.h create mode 100644 test/support/make_test_thread.h delete mode 100644 test/support/nasty_macros.h delete mode 100644 test/support/nothing_to_do.pass.cpp create mode 100644 test/support/operator_hijacker.h create mode 100644 test/support/parse_integer.h create mode 100644 test/support/pointer_comparison_test_helper.h create mode 100644 test/support/propagate_value_category.hpp create mode 100644 test/support/read_write.h create mode 100644 test/support/test.support/make_string_header.pass.cpp delete mode 100644 test/support/test.support/test_demangle.pass.cpp create mode 100644 test/support/test.support/test_macros_header.exceptions.pass.cpp create mode 100644 test/support/test.support/test_macros_header.no_exceptions.verify.cpp create mode 100644 test/support/test.support/test_macros_header.no_rtti.verify.cpp create mode 100644 test/support/test.support/test_macros_header.rtti.pass.cpp delete mode 100644 test/support/test.support/test_macros_header_exceptions.fail.cpp delete mode 100644 test/support/test.support/test_macros_header_exceptions.pass.cpp delete mode 100644 test/support/test.support/test_macros_header_rtti.fail.cpp delete mode 100644 test/support/test.support/test_macros_header_rtti.pass.cpp create mode 100644 test/support/test_basic_format_arg.h create mode 100644 test/support/test_constexpr_container.h create mode 100644 test/support/test_format_context.h create mode 100644 test/support/test_range.h create mode 100644 test/support/test_transparent_unordered.h delete mode 100644 test/support/tracked_value.h create mode 100644 test/support/type_classification/copyable.h create mode 100644 test/support/type_classification/movable.h create mode 100644 test/support/type_classification/moveconstructible.h create mode 100644 test/support/type_classification/semiregular.h create mode 100644 test/support/type_classification/swappable.h delete mode 100644 test/support/verbose_assert.h create mode 100644 utils/CMakeLists.txt create mode 100644 utils/ci/Dockerfile create mode 100755 utils/ci/apple-install-libcxx.sh create mode 100755 utils/ci/buildkite-pipeline-premerge.sh create mode 100755 utils/ci/buildkite-pipeline-snapshot.sh create mode 100644 utils/ci/buildkite-pipeline.yml delete mode 100755 utils/ci/macos-backdeployment.sh create mode 100755 utils/ci/macos-ci-setup delete mode 100755 utils/ci/macos-trunk.sh create mode 100755 utils/ci/oss-fuzz.sh create mode 100755 utils/ci/run-buildbot create mode 100755 utils/ci/run-buildbot-container delete mode 100644 utils/docker/debian9/Dockerfile.base delete mode 100644 utils/docker/debian9/Dockerfile.buildbot delete mode 100644 utils/docker/debian9/Dockerfile.clang delete mode 100644 utils/docker/debian9/Dockerfile.compiler_zoo delete mode 100644 utils/docker/debian9/Dockerfile.gcc delete mode 100644 utils/docker/docker-compose.yml delete mode 100755 utils/docker/scripts/build_gcc_version.sh delete mode 100755 utils/docker/scripts/build_llvm_version.sh delete mode 100755 utils/docker/scripts/docker_start_buildbots.sh delete mode 100755 utils/docker/scripts/docker_update_bot.sh delete mode 100755 utils/docker/scripts/install_clang_packages.sh delete mode 100755 utils/docker/scripts/run_buildbot.sh create mode 100755 utils/generate_abi_list.py create mode 100755 utils/generate_header_inclusion_tests.py create mode 100755 utils/generate_header_tests.py create mode 100755 utils/generate_private_header_tests.py delete mode 100644 utils/google-benchmark/.clang-format delete mode 100644 utils/google-benchmark/.gitignore delete mode 100644 utils/google-benchmark/.travis-libcxx-setup.sh delete mode 100644 utils/google-benchmark/.travis.yml delete mode 100644 utils/google-benchmark/.ycm_extra_conf.py delete mode 100644 utils/google-benchmark/AUTHORS delete mode 100644 utils/google-benchmark/CMakeLists.txt delete mode 100644 utils/google-benchmark/CONTRIBUTING.md delete mode 100644 utils/google-benchmark/CONTRIBUTORS delete mode 100644 utils/google-benchmark/LICENSE delete mode 100644 utils/google-benchmark/README.LLVM delete mode 100644 utils/google-benchmark/README.md delete mode 100644 utils/google-benchmark/WORKSPACE delete mode 100644 utils/google-benchmark/appveyor.yml delete mode 100644 utils/google-benchmark/cmake/AddCXXCompilerFlag.cmake delete mode 100644 utils/google-benchmark/cmake/CXXFeatureCheck.cmake delete mode 100644 utils/google-benchmark/cmake/Config.cmake.in delete mode 100644 utils/google-benchmark/cmake/GetGitVersion.cmake delete mode 100644 utils/google-benchmark/cmake/HandleGTest.cmake delete mode 100644 utils/google-benchmark/cmake/benchmark.pc.in delete mode 100644 utils/google-benchmark/cmake/gnu_posix_regex.cpp delete mode 100644 utils/google-benchmark/cmake/llvm-toolchain.cmake delete mode 100644 utils/google-benchmark/cmake/posix_regex.cpp delete mode 100644 utils/google-benchmark/cmake/split_list.cmake delete mode 100644 utils/google-benchmark/cmake/std_regex.cpp delete mode 100644 utils/google-benchmark/cmake/steady_clock.cpp delete mode 100644 utils/google-benchmark/cmake/thread_safety_attributes.cpp delete mode 100644 utils/google-benchmark/docs/AssemblyTests.md delete mode 100644 utils/google-benchmark/docs/tools.md delete mode 100644 utils/google-benchmark/include/benchmark/benchmark.h delete mode 100644 utils/google-benchmark/mingw.py delete mode 100644 utils/google-benchmark/releasing.md delete mode 100644 utils/google-benchmark/src/CMakeLists.txt delete mode 100644 utils/google-benchmark/src/arraysize.h delete mode 100644 utils/google-benchmark/src/benchmark.cc delete mode 100644 utils/google-benchmark/src/benchmark_api_internal.cc delete mode 100644 utils/google-benchmark/src/benchmark_api_internal.h delete mode 100644 utils/google-benchmark/src/benchmark_main.cc delete mode 100644 utils/google-benchmark/src/benchmark_register.cc delete mode 100644 utils/google-benchmark/src/benchmark_register.h delete mode 100644 utils/google-benchmark/src/benchmark_runner.cc delete mode 100644 utils/google-benchmark/src/benchmark_runner.h delete mode 100644 utils/google-benchmark/src/check.h delete mode 100644 utils/google-benchmark/src/colorprint.cc delete mode 100644 utils/google-benchmark/src/colorprint.h delete mode 100644 utils/google-benchmark/src/commandlineflags.cc delete mode 100644 utils/google-benchmark/src/commandlineflags.h delete mode 100644 utils/google-benchmark/src/complexity.cc delete mode 100644 utils/google-benchmark/src/complexity.h delete mode 100644 utils/google-benchmark/src/console_reporter.cc delete mode 100644 utils/google-benchmark/src/counter.cc delete mode 100644 utils/google-benchmark/src/counter.h delete mode 100644 utils/google-benchmark/src/csv_reporter.cc delete mode 100644 utils/google-benchmark/src/cycleclock.h delete mode 100644 utils/google-benchmark/src/internal_macros.h delete mode 100644 utils/google-benchmark/src/json_reporter.cc delete mode 100644 utils/google-benchmark/src/log.h delete mode 100644 utils/google-benchmark/src/mutex.h delete mode 100644 utils/google-benchmark/src/re.h delete mode 100644 utils/google-benchmark/src/reporter.cc delete mode 100644 utils/google-benchmark/src/sleep.cc delete mode 100644 utils/google-benchmark/src/sleep.h delete mode 100644 utils/google-benchmark/src/statistics.cc delete mode 100644 utils/google-benchmark/src/statistics.h delete mode 100644 utils/google-benchmark/src/string_util.cc delete mode 100644 utils/google-benchmark/src/string_util.h delete mode 100644 utils/google-benchmark/src/sysinfo.cc delete mode 100644 utils/google-benchmark/src/thread_manager.h delete mode 100644 utils/google-benchmark/src/thread_timer.h delete mode 100644 utils/google-benchmark/src/timers.cc delete mode 100644 utils/google-benchmark/src/timers.h delete mode 100644 utils/google-benchmark/test/AssemblyTests.cmake delete mode 100644 utils/google-benchmark/test/CMakeLists.txt delete mode 100644 utils/google-benchmark/test/basic_test.cc delete mode 100644 utils/google-benchmark/test/benchmark_gtest.cc delete mode 100644 utils/google-benchmark/test/benchmark_test.cc delete mode 100644 utils/google-benchmark/test/clobber_memory_assembly_test.cc delete mode 100644 utils/google-benchmark/test/complexity_test.cc delete mode 100644 utils/google-benchmark/test/cxx03_test.cc delete mode 100644 utils/google-benchmark/test/diagnostics_test.cc delete mode 100644 utils/google-benchmark/test/display_aggregates_only_test.cc delete mode 100644 utils/google-benchmark/test/donotoptimize_assembly_test.cc delete mode 100644 utils/google-benchmark/test/donotoptimize_test.cc delete mode 100644 utils/google-benchmark/test/filter_test.cc delete mode 100644 utils/google-benchmark/test/fixture_test.cc delete mode 100644 utils/google-benchmark/test/link_main_test.cc delete mode 100644 utils/google-benchmark/test/map_test.cc delete mode 100644 utils/google-benchmark/test/memory_manager_test.cc delete mode 100644 utils/google-benchmark/test/multiple_ranges_test.cc delete mode 100644 utils/google-benchmark/test/options_test.cc delete mode 100644 utils/google-benchmark/test/output_test.h delete mode 100644 utils/google-benchmark/test/output_test_helper.cc delete mode 100644 utils/google-benchmark/test/register_benchmark_test.cc delete mode 100644 utils/google-benchmark/test/report_aggregates_only_test.cc delete mode 100644 utils/google-benchmark/test/reporter_output_test.cc delete mode 100644 utils/google-benchmark/test/skip_with_error_test.cc delete mode 100644 utils/google-benchmark/test/state_assembly_test.cc delete mode 100644 utils/google-benchmark/test/statistics_gtest.cc delete mode 100644 utils/google-benchmark/test/string_util_gtest.cc delete mode 100644 utils/google-benchmark/test/templated_fixture_test.cc delete mode 100644 utils/google-benchmark/test/user_counters_tabular_test.cc delete mode 100644 utils/google-benchmark/test/user_counters_test.cc delete mode 100644 utils/google-benchmark/test/user_counters_thousands_test.cc delete mode 100755 utils/google-benchmark/tools/compare.py delete mode 100644 utils/google-benchmark/tools/gbench/Inputs/test1_run1.json delete mode 100644 utils/google-benchmark/tools/gbench/Inputs/test1_run2.json delete mode 100644 utils/google-benchmark/tools/gbench/Inputs/test2_run.json delete mode 100644 utils/google-benchmark/tools/gbench/Inputs/test3_run0.json delete mode 100644 utils/google-benchmark/tools/gbench/Inputs/test3_run1.json delete mode 100644 utils/google-benchmark/tools/gbench/__init__.py delete mode 100644 utils/google-benchmark/tools/gbench/report.py delete mode 100644 utils/google-benchmark/tools/gbench/util.py delete mode 100755 utils/google-benchmark/tools/strip_asm.py create mode 100755 utils/graph_header_deps.py create mode 100644 utils/libcxx/test/dsl.py delete mode 100644 utils/libcxx/test/executor.py create mode 100644 utils/libcxx/test/features.py create mode 100644 utils/libcxx/test/newconfig.py create mode 100644 utils/libcxx/test/params.py delete mode 100644 utils/libcxx/test/tracing.py delete mode 100644 utils/not.py mode change 100644 => 100755 utils/run.py create mode 100755 utils/ssh.py delete mode 100755 utils/sym_extract.py delete mode 100755 utils/sym_match.py delete mode 100644 www/atomic_design.html delete mode 100644 www/atomic_design_a.html delete mode 100644 www/atomic_design_b.html delete mode 100644 www/atomic_design_c.html delete mode 100644 www/content.css delete mode 100644 www/cxx1y_status.html delete mode 100644 www/cxx1z_status.html delete mode 100644 www/cxx2a_status.html delete mode 100644 www/index.html delete mode 100644 www/menu.css delete mode 100644 www/ts1z_status.html delete mode 100644 www/type_traits_design.html delete mode 100644 www/upcoming_meeting.html diff --git a/CMakeLists.txt.old b/CMakeLists.txt.old index 2fcb69467..358bd62d3 100644 --- a/CMakeLists.txt.old +++ b/CMakeLists.txt.old @@ -1,42 +1,58 @@ -# See www/CMake.html for instructions on how to build libcxx with CMake. +# See https://libcxx.llvm.org/docs/BuildingLibcxx.html for instructions on how +# to build libcxx with CMake. + +if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libcxxabi") + message(FATAL_ERROR "libc++ now requires being built in a monorepo layout with libcxxabi available") +endif() #=============================================================================== # Setup Project #=============================================================================== -cmake_minimum_required(VERSION 3.4.3) +cmake_minimum_required(VERSION 3.13.4) -if(POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default -endif() -if(POLICY CMP0022) - cmake_policy(SET CMP0022 NEW) # Required when interacting with LLVM and Clang -endif() +set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") # Add path for custom modules -set(CMAKE_MODULE_PATH +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" - ${CMAKE_MODULE_PATH} + "${LLVM_COMMON_CMAKE_UTILS}" + "${LLVM_COMMON_CMAKE_UTILS}/Modules" ) -if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) +set(CMAKE_FOLDER "libc++") + +set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build") + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUILD) + message(WARNING "The Standalone build is deprecated in this release. Please use one of the ways " + "described at https://libcxx.llvm.org/BuildingLibcxx.html for building libc++.") project(libcxx CXX C) set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 5.0.0svn) + set(PACKAGE_VERSION 14.0.6) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - # Find the LLVM sources and simulate LLVM CMake options. - include(HandleOutOfTreeLLVM) + # In a standalone build, we don't have llvm to automatically generate the + # llvm-lit script for us. So we need to provide an explicit directory that + # the configurator should write the script into. + set(LIBCXX_STANDALONE_BUILD TRUE) + set(LLVM_LIT_OUTPUT_DIR "${LIBCXX_BINARY_DIR}/bin") endif() +# Must go below project(..) +include(GNUInstallDirs) + if (LIBCXX_STANDALONE_BUILD) - include(FindPythonInterp) - if( NOT PYTHONINTERP_FOUND ) - message(WARNING "Failed to find python interpreter. " - "The libc++ test suite will be disabled.") - set(LLVM_INCLUDE_TESTS OFF) + # Find the LLVM sources and simulate LLVM CMake options. + include(HandleOutOfTreeLLVM) + + find_package(Python3 COMPONENTS Interpreter) + if(NOT Python3_Interpreter_FOUND) + message(SEND_ERROR "Python3 not found. Python3 is required") endif() endif() @@ -46,9 +62,14 @@ MACRO_ENSURE_OUT_OF_SOURCE_BUILD( "${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." ) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") + message(STATUS "Configuring for clang-cl") + set(LIBCXX_TARGETING_CLANG_CL ON) +endif() if (MSVC) set(LIBCXX_TARGETING_MSVC ON) + message(STATUS "Configuring for MSVC") else() set(LIBCXX_TARGETING_MSVC OFF) endif() @@ -64,12 +85,73 @@ option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." O option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON) option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) -option(LIBCXX_ENABLE_FILESYSTEM - "Build filesystem as part of libc++experimental.a" ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY}) +set(ENABLE_FILESYSTEM_DEFAULT ON) +if (WIN32 AND NOT MINGW) + # Filesystem is buildable for windows, but it requires __int128 helper + # functions, that currently are provided by libgcc or compiler_rt builtins. + # These are available in MinGW environments, but not currently in MSVC + # environments. + set(ENABLE_FILESYSTEM_DEFAULT OFF) +endif() +option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ library" + ${ENABLE_FILESYSTEM_DEFAULT}) option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS}) +option(LIBCXX_ENABLE_PARALLEL_ALGORITHMS "Enable the parallel algorithms library. This requires the PSTL to be available." OFF) +option(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT + "Whether to include support for libc++'s debugging mode in the library. + By default, this is turned on. If you turn it off and try to enable the + debug mode when compiling a program against libc++, it will fail to link + since the required support isn't provided in the library." ON) +option(LIBCXX_ENABLE_RANDOM_DEVICE + "Whether to include support for std::random_device in the library. Disabling + this can be useful when building the library for platforms that don't have + a source of randomness, such as some embedded platforms. When this is not + supported, most of will still be available, but std::random_device + will not." ON) +option(LIBCXX_ENABLE_LOCALIZATION + "Whether to include support for localization in the library. Disabling + localization can be useful when porting to platforms that don't support + the C locale API (e.g. embedded). When localization is not supported, + several parts of the library will be disabled: , , + will be completely unusable, and other parts may be only partly available." ON) +option(LIBCXX_ENABLE_UNICODE + "Whether to include support for Unicode in the library. Disabling Unicode can + be useful when porting to platforms that don't support UTF-8 encoding (e.g. + embedded)." ON) +option(LIBCXX_ENABLE_WIDE_CHARACTERS + "Whether to include support for wide characters in the library. Disabling + wide character support can be useful when porting to platforms that don't + support the C functionality for wide characters. When wide characters are + not supported, several parts of the library will be disabled, notably the + wide character specializations of std::basic_string." ON) +option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS + "Whether to turn on vendor availability annotations on declarations that depend + on definitions in a shared library. By default, we assume that we're not building + libc++ for any specific vendor, and we disable those annotations. Vendors wishing + to provide compile-time errors when using features unavailable on some version of + the shared library they shipped should turn this on and see `include/__availability` + for more details." OFF) +option(LIBCXX_ENABLE_INCOMPLETE_FEATURES + "Whether to enable support for incomplete library features. Incomplete features + are new library features under development. These features don't guarantee + ABI stability nor the quality of completed library features. Vendors + shipping the library may want to disable this option." OFF) +set(LIBCXX_TEST_CONFIG "legacy.cfg.in" CACHE STRING + "The path to the Lit testing configuration to use when running the tests. + If a relative path is provided, it is assumed to be relative to '/libcxx/test/configs'.") +if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}") + set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}") +endif() +set(LIBCXX_TEST_PARAMS "" CACHE STRING + "A list of parameters to run the Lit test suite with.") # Benchmark options ----------------------------------------------------------- -option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependancies" ON) +option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON) + +set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01) +set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING + "Arguments to pass when running the benchmarks using check-cxx-benchmarks") + set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING "Build the benchmarks against the specified native STL. The value must be one of libc++/libstdc++") @@ -87,61 +169,76 @@ endif() option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS}) set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") -option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." OFF) -option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." OFF) -option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." OFF) +option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) +option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON) +cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY + "Install the static libc++ library." ON + "LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF) +cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY + "Install the shared libc++ library." ON + "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF) cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY - "Install libc++experimental.a" OFF + "Install libc++experimental.a" ON "LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF) -set(LIBCXX_ABI_VERSION 1 CACHE STRING "ABI version of libc++.") -option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) -option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) -if (NOT LIBCXX_ENABLE_SHARED AND NOT LIBCXX_ENABLE_STATIC) - message(FATAL_ERROR "libc++ must be built as either a shared or static library.") +set(LIBCXX_ABI_VERSION "1" CACHE STRING "ABI version of libc++. Can be either 1 or 2, where 2 is currently not stable. Defaults to 1.") +set(LIBCXX_ABI_NAMESPACE "" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.") +option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) +option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.") +option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.") + +set(LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION "default" CACHE STRING + "Override the implementation to use for comparing typeinfos. By default, this + is detected automatically by the library, but this option allows overriding + which implementation is used unconditionally. + + See the documentation in for details on what each + value means.") +set(TYPEINFO_COMPARISON_VALUES "default;1;2;3") +if (NOT ("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" IN_LIST TYPEINFO_COMPARISON_VALUES)) + message(FATAL_ERROR "Value '${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}' is not a valid value for + LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION") endif() +option(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT "Enable per TU ABI insulation by default. To be used by vendors." OFF) +set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.") +option(LIBCXX_EXTRA_SITE_DEFINES "Extra defines to add into __config_site") +option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) +set(LIBCXX_LIBCPPABI_VERSION "2" CACHE STRING "Version of libc++abi's ABI to re-export from libc++ when re-exporting is enabled. + Note that this is not related to the version of libc++'s ABI itself!") + # ABI Library options --------------------------------------------------------- -set(LIBCXX_CXX_ABI "default" CACHE STRING - "Specify C++ ABI library to use.") +set(LIBCXX_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++ vcruntime) set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) -set(LIBCXX_CXX_ABI "libcxxabi") -set(LIBCXX_CXX_ABI_INTREE 1) - # Setup the default options if LIBCXX_CXX_ABI is not specified. if (LIBCXX_CXX_ABI STREQUAL "default") - find_path( - LIBCXX_LIBCXXABI_INCLUDES_INTERNAL - cxxabi.h - PATHS ${LLVM_MAIN_SRC_DIR}/projects/libcxxabi/include - ${LLVM_MAIN_SRC_DIR}/runtimes/libcxxabi/include - NO_DEFAULT_PATH - ) - if ((NOT LIBCXX_STANDALONE_BUILD OR HAVE_LIBCXXABI) AND - IS_DIRECTORY "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}") + if (LIBCXX_TARGETING_MSVC) + # FIXME: Figure out how to configure the ABI library on Windows. + set(LIBCXX_CXX_ABI_LIBNAME "vcruntime") + elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + set(LIBCXX_CXX_ABI_LIBNAME "libcxxrt") + elseif (NOT LIBCXX_STANDALONE_BUILD OR HAVE_LIBCXXABI) set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi") - set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_LIBCXXABI_INCLUDES_INTERNAL}") - set(LIBCXX_CXX_ABI_INTREE 1) else() - if (LIBCXX_TARGETING_MSVC) - # FIXME: Figure out how to configure the ABI library on Windows. - set(LIBCXX_CXX_ABI_LIBNAME "vcruntime") - elseif(APPLE) - set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi") - set(LIBCXX_CXX_ABI_SYSTEM 1) - else() - set(LIBCXX_CXX_ABI_LIBNAME "default") - endif() + set(LIBCXX_CXX_ABI_LIBNAME "default") endif() else() set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}") endif() -# Use a static copy of the ABI library when linking libc++. This option -# cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT. -option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF) +option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY + "Use a static copy of the ABI library when linking libc++. + This option cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT." OFF) + +cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY + "Statically link the ABI library to static library" ON + "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_STATIC" OFF) + +cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY + "Statically link the ABI library to shared library" ON + "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_SHARED" OFF) # Generate and install a linker script inplace of libc++.so. The linker script # will link libc++ to the correct ABI library. This option is on by default @@ -149,10 +246,10 @@ option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF) # is on. This option is also disabled when the ABI library is not specified # or is specified to be "none". set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF) -if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY +if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "none" AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "default" - AND PYTHONINTERP_FOUND + AND Python3_EXECUTABLE AND LIBCXX_ENABLE_SHARED) set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON) endif() @@ -161,44 +258,50 @@ option(LIBCXX_ENABLE_ABI_LINKER_SCRIPT "Use and install a linker script for the given ABI library" ${ENABLE_LINKER_SCRIPT_DEFAULT_VALUE}) -set(ENABLE_NEW_DELETE_DEFAULT ON) -if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS) -# FIXME: This option should default to off. Unfortunatly GCC 4.9 fails to link -# programs due to undefined references to new/delete in libc++abi so to work -# around this libc++abi currently defaults LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS -# to ON. Once the GCC bug has been worked around this option should be changed -# back to OFF. - set(ENABLE_NEW_DELETE_DEFAULT ON) -endif() - option(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS - "Build libc++ with definitions for operator new/delete. This option can - be used to disable the definitions when libc++abi is expected to provide - them" ${ENABLE_NEW_DELETE_DEFAULT}) - + "Build libc++ with definitions for operator new/delete. These are normally + defined in libc++abi, but this option can be used to define them in libc++ + instead. If you define them in libc++, make sure they are NOT defined in + libc++abi. Doing otherwise is an ODR violation." OFF) # Build libc++abi with libunwind. We need this option to determine whether to # link with libunwind or libgcc_s while running the test cases. option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF) -option(LIBCXXABI_ENABLE_STATIC_UNWINDER "Statically link the LLVM unwinder." OFF) # Target options -------------------------------------------------------------- -option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++." ${LLVM_BUILD_32_BITS}) -set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.") -set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.") +option(LIBCXX_BUILD_32_BITS "Build 32 bit multilib libc++. This option is not supported anymore when building the runtimes. Please specify a full triple instead." ${LLVM_BUILD_32_BITS}) +if (LIBCXX_BUILD_32_BITS) + message(FATAL_ERROR "LIBCXX_BUILD_32_BITS is not supported anymore when building the runtimes, please specify a full triple instead.") +endif() + +if(NOT CMAKE_SYSROOT AND LIBCXX_SYSROOT) + message(WARNING "LIBCXX_SYSROOT is deprecated, please use CMAKE_SYSROOT instead") +endif() +if(NOT CMAKE_CXX_COMPILER_TARGET AND LIBCXX_TARGET_TRIPLE) + message(WARNING "LIBCXX_TARGET_TRIPLE is deprecated, please use CMAKE_CXX_COMPILER_TARGET instead") +endif() +if(NOT CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN AND LIBCXX_GCC_TOOLCHAIN) + message(WARNING "LIBCXX_GCC_TOOLCHAIN is deprecated, please use CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN instead") +endif() + +if(CMAKE_CXX_COMPILER_TARGET) + set(LIBCXX_DEFAULT_TARGET_TRIPLE "${CMAKE_CXX_COMPILER_TARGET}") +else() + set(LIBCXX_DEFAULT_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}") +endif() +set(LIBCXX_TARGET_TRIPLE "${LIBCXX_DEFAULT_TARGET_TRIPLE}" CACHE STRING "Use alternate target triple.") +set(LIBCXX_SYSROOT "${CMAKE_SYSROOT}" CACHE STRING "Use alternate sysroot.") +set(LIBCXX_GCC_TOOLCHAIN "${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}" CACHE STRING "Use alternate GCC toolchain.") # Feature options ------------------------------------------------------------- option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON) option(LIBCXX_ENABLE_RTTI "Use run time type information." ON) -option(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE "Build libc++ with support for the global filesystem namespace." ON) -option(LIBCXX_ENABLE_STDIN "Build libc++ with support for stdin/std::cin." ON) -option(LIBCXX_ENABLE_STDOUT "Build libc++ with support for stdout/std::cout." ON) option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON) -option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON) option(LIBCXX_ENABLE_MONOTONIC_CLOCK "Build libc++ with support for a monotonic clock. This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON) option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF) option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF) +option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF) option(LIBCXX_HAS_EXTERNAL_THREAD_API "Build libc++ with an externalized threading API. This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF) @@ -217,23 +320,6 @@ option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF) set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING "The Profile-rt library used to build with code coverage") -# Don't allow a user to accidentally overwrite the system libc++ installation on Darwin. -# If the user specifies -DCMAKE_INSTALL_PREFIX=/usr the install rules for libc++ -# will not be generated and a warning will be issued. -option(LIBCXX_OVERRIDE_DARWIN_INSTALL "Enable overwriting darwins libc++ installation." OFF) -mark_as_advanced(LIBCXX_OVERRIDE_DARWIN_INSTALL) # Don't show this option by default. - -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT LIBCXX_OVERRIDE_DARWIN_INSTALL) - if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr") - message(WARNING "Disabling libc++ install rules because installation would " - "overwrite the systems installation. Configure with " - "-DLIBCXX_OVERRIDE_DARWIN_INSTALL=ON to suppress this behaviour.") - mark_as_advanced(CLEAR LIBCXX_OVERRIDE_DARWIN_INSTALL) # Show the override option. - set(LIBCXX_INSTALL_HEADERS OFF) - set(LIBCXX_INSTALL_LIBRARY OFF) - endif() -endif() - set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF) if (XCODE OR MSVC_IDE) set(LIBCXX_CONFIGURE_IDE_DEFAULT ON) @@ -241,15 +327,13 @@ endif() option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE" ${LIBCXX_CONFIGURE_IDE_DEFAULT}) +option(LIBCXX_HERMETIC_STATIC_LIBRARY + "Do not export any symbols from the static library." OFF) + #=============================================================================== # Check option configurations #=============================================================================== -if (LIBCXX_ENABLE_FILESYSTEM AND NOT LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) - message(FATAL_ERROR - "LIBCXX_ENABLE_FILESYSTEM cannot be turned on when LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF") -endif() - # Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when # LIBCXX_ENABLE_THREADS is on. if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK) @@ -270,6 +354,10 @@ if(NOT LIBCXX_ENABLE_THREADS) message(FATAL_ERROR "LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY can only be set " "to ON when LIBCXX_ENABLE_THREADS is also set to ON.") endif() + if (LIBCXX_HAS_WIN32_THREAD_API) + message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON" + " when LIBCXX_ENABLE_THREADS is also set to ON.") + endif() endif() @@ -284,6 +372,19 @@ if (LIBCXX_HAS_EXTERNAL_THREAD_API) "and LIBCXX_HAS_PTHREAD_API cannot be both" "set to ON at the same time.") endif() + if (LIBCXX_HAS_WIN32_THREAD_API) + message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API" + "and LIBCXX_HAS_WIN32_THREAD_API cannot be both" + "set to ON at the same time.") + endif() +endif() + +if (LIBCXX_HAS_PTHREAD_API) + if (LIBCXX_HAS_WIN32_THREAD_API) + message(FATAL_ERROR "The options LIBCXX_HAS_PTHREAD_API" + "and LIBCXX_HAS_WIN32_THREAD_API cannot be both" + "set to ON at the same time.") + endif() endif() # Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE @@ -292,24 +393,10 @@ if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE) message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE") endif() -# Set LIBCXX_BUILD_32_BITS to (LIBCXX_BUILD_32_BITS OR LLVM_BUILD_32_BITS) -# and check that we can build with 32 bits if requested. -if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32) - if (LIBCXX_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM - message(STATUS "Building 32 bits executables and libraries.") - endif() -elseif(LIBCXX_BUILD_32_BITS) - message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.") -endif() - -# Check that this option is not enabled on Apple and emit a usage warning. +# Warn users that LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option. if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) - if (APPLE) - message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is not supported on OS X") - else() - message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option") - endif() - if (LIBCXX_ENABLE_STATIC AND NOT PYTHONINTERP_FOUND) + message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option") + if (LIBCXX_ENABLE_STATIC AND NOT Python3_EXECUTABLE) message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY requires python but it was not found.") endif() endif() @@ -318,48 +405,75 @@ if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) if (APPLE) message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets") endif() - if (NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT requires python but it was not found.") - endif() if (NOT LIBCXX_ENABLE_SHARED) message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT is only available for shared library builds.") endif() endif() -if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT) +if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT) message(FATAL_ERROR "Conflicting options given. LIBCXX_ENABLE_STATIC_ABI_LIBRARY cannot be specified with LIBCXX_ENABLE_ABI_LINKER_SCRIPT") endif() -if (LIBCXX_HAS_MUSL_LIBC AND NOT LIBCXX_INSTALL_SUPPORT_HEADERS) - message(FATAL_ERROR "LIBCXX_INSTALL_SUPPORT_HEADERS can not be turned off" - "when building for Musl with LIBCXX_HAS_MUSL_LIBC.") -endif() +if (LIBCXX_ABI_FORCE_ITANIUM AND LIBCXX_ABI_FORCE_MICROSOFT) + message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.") +endif () #=============================================================================== # Configure System #=============================================================================== -set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER}) -set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build") -set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) +# TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR +# instead of hard-coding include/c++/v1. + +set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH + "Path where target-agnostic libc++ headers should be installed.") +set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH + "Path where built libc++ runtime libraries should be installed.") + +if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libc++ libraries should be installed.") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH + "Path where target-specific libc++ headers should be installed.") + if(LIBCXX_LIBDIR_SUBDIR) + string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) + string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) + endif() +else() + if(LLVM_LIBRARY_OUTPUT_INTDIR) + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + else() + set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") + endif() + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH + "Path where built libc++ libraries should be installed.") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH + "Path where target-specific libc++ headers should be installed.") +endif() + file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) # Declare libc++ configuration variables. # They are intended for use as follows: # LIBCXX_CXX_FLAGS: General flags for both the compiler and linker. # LIBCXX_COMPILE_FLAGS: Compile only flags. # LIBCXX_LINK_FLAGS: Linker only flags. -set(LIBCXX_COMPILE_FLAGS "-nostdinc -nostdlib") +# LIBCXX_LIBRARIES: libraries libc++ is linked to. +set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") -set(LIBCXX_INTERFACE_LIBRARIES "") # Include macros for adding and removing libc++ flags. include(HandleLibcxxFlags) @@ -368,21 +482,22 @@ include(HandleLibcxxFlags) # These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that # 'config-ix' use them during feature checks. It also adds them to both # 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS' -add_target_flags_if(LIBCXX_BUILD_32_BITS "-m32") -add_target_flags_if(LIBCXX_TARGET_TRIPLE "-target ${LIBCXX_TARGET_TRIPLE}") -add_target_flags_if(LIBCXX_SYSROOT "--sysroot=${LIBCXX_SYSROOT}") -add_target_flags_if(LIBCXX_GCC_TOOLCHAIN "-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}") -if (LIBCXX_TARGET_TRIPLE) - set(TARGET_TRIPLE "${LIBCXX_TARGET_TRIPLE}") +if(ZOS) + add_target_flags_if_supported("-fzos-le-char-mode=ebcdic") +endif() +if(LIBCXX_TARGET_TRIPLE) + add_target_flags_if_supported("--target=${LIBCXX_TARGET_TRIPLE}") +endif() +if(LIBCXX_SYSROOT) + add_target_flags_if_supported("--sysroot=${LIBCXX_SYSROOT}") +endif() +if(LIBCXX_GCC_TOOLCHAIN) + add_target_flags_if_supported("--gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}") endif() # Configure compiler. include(config-ix) -if (LIBCXX_USE_COMPILER_RT) - list(APPEND LIBCXX_LINK_FLAGS "-rtlib=compiler-rt") -endif() - # Configure coverage options. if (LIBCXX_GENERATE_COVERAGE) include(CodeCoverage) @@ -407,7 +522,7 @@ if (NOT LIBCXX_STANDALONE_BUILD) remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG -lc++abi) endif() -remove_flags(-stdlib=libc++ -stdlib=libstdc++) +remove_flags(--stdlib=libc++ -stdlib=libc++ --stdlib=libstdc++ -stdlib=libstdc++) # FIXME: Remove all debug flags and flags that change which Windows # default libraries are linked. Currently we only support linking the @@ -420,86 +535,146 @@ remove_flags("/D_DEBUG" "/MTd" "/MDd" "/MT" "/Md") remove_flags(-Wno-pedantic -pedantic-errors -pedantic) # Required flags ============================================================== -set(LIBCXX_STANDARD_VER c++11 CACHE INTERNAL "internal option to change build dialect") -if (LIBCXX_HAS_MUSL_LIBC) - # musl's pthread implementations uses volatile types in their structs which is - # not a constexpr in C++11 but is in C++14, so we use C++14 with musl. - set(LIBCXX_STANDARD_VER c++14 CACHE INTERNAL "internal option to change build dialect") -endif() -add_compile_flags_if_supported(-std=${LIBCXX_STANDARD_VER}) -mangle_name("LIBCXX_SUPPORTS_STD_EQ_${LIBCXX_STANDARD_VER}_FLAG" SUPPORTS_DIALECT_NAME) -if(NOT ${SUPPORTS_DIALECT_NAME}) - if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") - message(FATAL_ERROR "C++11 or greater is required but the compiler does not support ${LIBCXX_STANDARD_VER}") +function(cxx_add_basic_build_flags target) + + # Require C++20 for all targets. C++17 is needed to use aligned allocation + # in the dylib. C++20 is needed to use char8_t. + set_target_properties(${target} PROPERTIES + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + + # When building the dylib, don't warn for unavailable aligned allocation + # functions based on the deployment target -- they are always available + # because they are provided by the dylib itself with the excepton of z/OS. + if (ZOS) + target_add_compile_flags_if_supported(${target} PRIVATE -fno-aligned-allocation) + else() + target_add_compile_flags_if_supported(${target} PRIVATE -faligned-allocation) endif() -endif() -# On all systems the system c++ standard library headers need to be excluded. -# MSVC only has -X, which disables all default includes; including the crt. -# Thus, we do nothing and hope we don't accidentally include any of the C++ -# headers -add_compile_flags_if_supported(-nostdinc++) + # On all systems the system c++ standard library headers need to be excluded. + # MSVC only has -X, which disables all default includes; including the crt. + # Thus, we do nothing and hope we don't accidentally include any of the C++ + # headers + target_add_compile_flags_if_supported(${target} PUBLIC -nostdinc++) -# Hide all inline function definitions which have not explicitly been marked -# visible. This prevents new definitions for inline functions from appearing in -# the dylib when get ODR used by another function. -add_compile_flags_if_supported(-fvisibility-inlines-hidden) + # Hide all inline function definitions which have not explicitly been marked + # visible. This prevents new definitions for inline functions from appearing in + # the dylib when get ODR used by another function. + target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility-inlines-hidden) -# Let the library headers know they are currently being used to build the -# library. -add_definitions(-D_LIBCPP_BUILDING_LIBRARY) + # Our visibility annotations are not quite right for non-Clang compilers, + # so we end up not exporting all the symbols we should. In the future, we + # can improve the situation by providing an explicit list of exported + # symbols on all compilers. + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility=hidden) + endif() -if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS) - add_definitions(-D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) -endif() + if (LIBCXX_CONFIGURE_IDE) + # This simply allows IDE to process + target_add_compile_flags_if_supported(${target} PRIVATE -fcoroutines-ts) + endif() + + # Let the library headers know they are currently being used to build the + # library. + target_compile_definitions(${target} PRIVATE -D_LIBCPP_BUILDING_LIBRARY) + + if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS) + target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) + endif() + + if (LIBCXX_HAS_COMMENT_LIB_PRAGMA) + if (LIBCXX_HAS_PTHREAD_LIB) + target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_PTHREAD_LIB) + endif() + if (LIBCXX_HAS_RT_LIB) + target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB) + endif() + endif() +endfunction() # Warning flags =============================================================== -add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -add_compile_flags_if_supported( - -Wall -Wextra -W -Wwrite-strings - -Wno-unused-parameter -Wno-long-long - -Werror=return-type) -if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - add_compile_flags_if_supported( - -Wno-user-defined-literals - -Wno-covered-switch-default) -elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - add_compile_flags_if_supported( - -Wno-literal-suffix - -Wno-c++14-compat) -endif() -if (LIBCXX_ENABLE_WERROR) - add_compile_flags_if_supported(-Werror) - add_compile_flags_if_supported(-WX) -else() - # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is - # added elsewhere. - add_compile_flags_if_supported(-Wno-error) -endif() -if (LIBCXX_ENABLE_PEDANTIC) - add_compile_flags_if_supported(-pedantic) -endif() -if (LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS) - add_definitions(-D_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) -endif() +function(cxx_add_warning_flags target) + target_compile_definitions(${target} PUBLIC -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) + if (MSVC) + # -W4 is the cl.exe/clang-cl equivalent of -Wall. (In cl.exe and clang-cl, + # -Wall is equivalent to -Weverything in GCC style compiler drivers.) + target_add_compile_flags_if_supported(${target} PRIVATE -W4) + else() + target_add_compile_flags_if_supported(${target} PRIVATE -Wall) + endif() + target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings + -Wno-unused-parameter -Wno-long-long + -Werror=return-type -Wextra-semi -Wundef + -Wformat-nonliteral) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + target_add_compile_flags_if_supported(${target} PRIVATE + -Wno-user-defined-literals + -Wno-covered-switch-default + -Wno-suggest-override + ) + if (LIBCXX_TARGETING_CLANG_CL) + target_add_compile_flags_if_supported(${target} PRIVATE + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-c++11-compat + -Wno-undef + -Wno-reserved-id-macro + -Wno-gnu-include-next + -Wno-gcc-compat # For ignoring "'diagnose_if' is a clang extension" warnings + -Wno-zero-as-null-pointer-constant # FIXME: Remove this and fix all occurrences. + -Wno-deprecated-dynamic-exception-spec # For auto_ptr + -Wno-sign-conversion + -Wno-old-style-cast + -Wno-deprecated # FIXME: Remove this and fix all occurrences. + -Wno-shift-sign-overflow # FIXME: Why do we need this with clang-cl but not clang? + -Wno-double-promotion # FIXME: remove me + ) + endif() + elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + target_add_compile_flags_if_supported(${target} PRIVATE + -Wno-literal-suffix + -Wno-c++14-compat + -Wno-noexcept-type + -Wno-suggest-override) + endif() + if (LIBCXX_ENABLE_WERROR) + target_add_compile_flags_if_supported(${target} PRIVATE -Werror) + target_add_compile_flags_if_supported(${target} PRIVATE -WX) + else() + # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is + # added elsewhere. + target_add_compile_flags_if_supported(${target} PRIVATE -Wno-error) + endif() + if (LIBCXX_ENABLE_PEDANTIC) + target_add_compile_flags_if_supported(${target} PRIVATE -pedantic) + endif() + if (LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS) + target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) + endif() +endfunction() # Exception flags ============================================================= -if (LIBCXX_ENABLE_EXCEPTIONS) - # Catches C++ exceptions only and tells the compiler to assume that extern C - # functions never throw a C++ exception. - add_compile_flags_if_supported(-EHsc) -else() - add_definitions(-D_LIBCPP_NO_EXCEPTIONS) - add_compile_flags_if_supported(-EHs- -EHa-) - add_compile_flags_if_supported(-fno-exceptions) -endif() +function(cxx_add_exception_flags target) + if (LIBCXX_ENABLE_EXCEPTIONS) + # Catches C++ exceptions only and tells the compiler to assume that extern C + # functions never throw a C++ exception. + target_add_compile_flags_if_supported(${target} PUBLIC -EHsc) + else() + target_add_compile_flags_if_supported(${target} PUBLIC -EHs- -EHa-) + target_add_compile_flags_if_supported(${target} PUBLIC -fno-exceptions) + endif() +endfunction() # RTTI flags ================================================================== -if (NOT LIBCXX_ENABLE_RTTI) - add_definitions(-D_LIBCPP_NO_RTTI) - add_compile_flags_if_supported(-GR-) - add_compile_flags_if_supported(-fno-rtti) -endif() +function(cxx_add_rtti_flags target) + if (NOT LIBCXX_ENABLE_RTTI) + target_add_compile_flags_if_supported(${target} PUBLIC -GR-) + target_add_compile_flags_if_supported(${target} PUBLIC -fno-rtti) + endif() +endfunction() # Threading flags ============================================================= if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_ENABLE_SHARED) @@ -526,65 +701,235 @@ endif() # FIXME The libc++ sources are fundamentally non-modular. They need special # versions of the headers in order to provide C++03 and legacy ABI definitions. # NOTE: The public headers can be used with modules in all other contexts. -if (LLVM_ENABLE_MODULES) - # Ignore that the rest of the modules flags are now unused. - add_compile_flags_if_supported(-Wno-unused-command-line-argument) - add_compile_flags(-fno-modules) -endif() +function(cxx_add_module_flags target) + if (LLVM_ENABLE_MODULES) + # Ignore that the rest of the modules flags are now unused. + target_add_compile_flags_if_supported(${target} PUBLIC -Wno-unused-command-line-argument) + target_compile_options(${target} PUBLIC -fno-modules) + endif() +endfunction() # Sanitizer flags ============================================================= +function(get_sanitizer_flags OUT_VAR USE_SANITIZER) + set(SANITIZER_FLAGS) + set(USE_SANITIZER "${USE_SANITIZER}") + # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC. + # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do. + if (USE_SANITIZER AND NOT MSVC) + append_flags_if_supported(SANITIZER_FLAGS "-fno-omit-frame-pointer") + append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only") + + if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND + NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO") + append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only") + endif() + if (USE_SANITIZER STREQUAL "Address") + append_flags(SANITIZER_FLAGS "-fsanitize=address") + elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?") + append_flags(SANITIZER_FLAGS -fsanitize=memory) + if (USE_SANITIZER STREQUAL "MemoryWithOrigins") + append_flags(SANITIZER_FLAGS "-fsanitize-memory-track-origins") + endif() + elseif (USE_SANITIZER STREQUAL "Undefined") + append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all") + elseif (USE_SANITIZER STREQUAL "Address;Undefined" OR + USE_SANITIZER STREQUAL "Undefined;Address") + append_flags(SANITIZER_FLAGS "-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all") + elseif (USE_SANITIZER STREQUAL "Thread") + append_flags(SANITIZER_FLAGS -fsanitize=thread) + elseif (USE_SANITIZER STREQUAL "DataFlow") + append_flags(SANITIZER_FLAGS -fsanitize=dataflow) + else() + message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}") + endif() + elseif(USE_SANITIZER AND MSVC) + message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") + endif() + set(${OUT_VAR} "${SANITIZER_FLAGS}" PARENT_SCOPE) +endfunction() + # Configure for sanitizers. If LIBCXX_STANDALONE_BUILD then we have to do # the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it. if (LIBCXX_STANDALONE_BUILD) set(LLVM_USE_SANITIZER "" CACHE STRING "Define the sanitizer used to build the library and tests") - # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC. - # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do. - if (LLVM_USE_SANITIZER AND NOT MSVC) - add_flags_if_supported("-fno-omit-frame-pointer") - add_flags_if_supported("-gline-tables-only") - - if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND - NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO") - add_flags_if_supported("-gline-tables-only") - endif() - if (LLVM_USE_SANITIZER STREQUAL "Address") - add_flags("-fsanitize=address") - elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?") - add_flags(-fsanitize=memory) - if (LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins") - add_flags("-fsanitize-memory-track-origins") - endif() - elseif (LLVM_USE_SANITIZER STREQUAL "Undefined") - add_flags("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all") - elseif (LLVM_USE_SANITIZER STREQUAL "Thread") - add_flags(-fsanitize=thread) - else() - message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}") - endif() - elseif(LLVM_USE_SANITIZER AND MSVC) - message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") - endif() endif() +get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}") +if (LIBCXX_STANDALONE_BUILD AND SANITIZER_FLAGS) + add_flags(${SANITIZER_FLAGS}) +endif() + +# Link system libraries ======================================================= +function(cxx_link_system_libraries target) + +# In order to remove just libc++ from the link step +# we need to use -nostdlib++ whenever it is supported. +# Unfortunately this cannot be used universally because for example g++ supports +# only -nodefaultlibs in which case all libraries will be removed and +# all libraries but c++ have to be added in manually. + if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) + target_add_link_flags_if_supported(${target} PRIVATE "-nostdlib++") + else() + target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs") + target_add_compile_flags_if_supported(${target} PRIVATE "/Zl") + target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib") + endif() + + if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER) + # If we're linking directly against the libunwind that we're building + # in the same invocation, don't try to link in the toolchain's + # default libunwind (which may be missing still). + target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none") + endif() + + if (LIBCXX_HAS_SYSTEM_LIB) + target_link_libraries(${target} PRIVATE System) + endif() + + if (LIBCXX_HAS_PTHREAD_LIB) + target_link_libraries(${target} PRIVATE pthread) + endif() + + if (LIBCXX_HAS_C_LIB) + target_link_libraries(${target} PRIVATE c) + endif() + + if (LIBCXX_HAS_M_LIB) + target_link_libraries(${target} PRIVATE m) + endif() + + if (LIBCXX_HAS_RT_LIB) + target_link_libraries(${target} PRIVATE rt) + endif() + + if (LIBCXX_USE_COMPILER_RT) + find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) + if (LIBCXX_BUILTINS_LIBRARY) + target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}") + endif() + elseif (LIBCXX_HAS_GCC_LIB) + target_link_libraries(${target} PRIVATE gcc) + elseif (LIBCXX_HAS_GCC_S_LIB) + target_link_libraries(${target} PRIVATE gcc_s) + endif() + + if (LIBCXX_HAS_ATOMIC_LIB) + target_link_libraries(${target} PRIVATE atomic) + endif() + + if (MINGW) + target_link_libraries(${target} PRIVATE "${MINGW_LIBRARIES}") + endif() + + if (LIBCXX_TARGETING_MSVC) + if (LIBCXX_DEBUG_BUILD) + set(LIB_SUFFIX "d") + else() + set(LIB_SUFFIX "") + endif() + + target_link_libraries(${target} PRIVATE ucrt${LIB_SUFFIX}) # Universal C runtime + target_link_libraries(${target} PRIVATE vcruntime${LIB_SUFFIX}) # C++ runtime + target_link_libraries(${target} PRIVATE msvcrt${LIB_SUFFIX}) # C runtime startup files + target_link_libraries(${target} PRIVATE msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals. + # Required for standards-complaint wide character formatting functions + # (e.g. `printfw`/`scanfw`) + target_link_libraries(${target} PRIVATE iso_stdio_wide_specifiers) + endif() + + if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21) + target_link_libraries(${target} PUBLIC android_support) + endif() +endfunction() + +# Windows-related flags ======================================================= +function(cxx_add_windows_flags target) + if(WIN32 AND NOT MINGW) + target_compile_definitions(${target} PRIVATE + # Ignore the -MSC_VER mismatch, as we may build + # with a different compatibility version. + _ALLOW_MSC_VER_MISMATCH + # Don't check the msvcprt iterator debug levels + # as we will define the iterator types; libc++ + # uses a different macro to identify the debug + # level. + _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH + # We are building the c++ runtime, don't pull in + # msvcprt. + _CRTBLD + # Don't warn on the use of "deprecated" + # "insecure" functions which are standards + # specified. + _CRT_SECURE_NO_WARNINGS + # Use the ISO conforming behaviour for conversion + # in printf, scanf. + _CRT_STDIO_ISO_WIDE_SPECIFIERS) + endif() +endfunction() # Configuration file flags ===================================================== -if (NOT LIBCXX_ABI_VERSION EQUAL "1") +if (NOT LIBCXX_ABI_VERSION EQUAL 1) config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION) endif() +if (NOT LIBCXX_ABI_NAMESPACE STREQUAL "") + if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*") + message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier.") + endif() + if (LIBCXX_ABI_NAMESPACE MATCHES "__[0-9]+$") + message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE '${LIBCXX_ABI_NAMESPACE}' is reserved for use by libc++.") + endif() + config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE) +endif() config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE) - -config_define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) -config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN) -config_define_if_not(LIBCXX_ENABLE_STDOUT _LIBCPP_HAS_NO_STDOUT) +config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM) +config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT) +config_define_if(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT) config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS) config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK) -config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) - +if (NOT LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION STREQUAL "default") + config_define("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION) +endif() config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD) config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL) +config_define_if(LIBCXX_HAS_WIN32_THREAD_API _LIBCPP_HAS_THREAD_API_WIN32) config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC) +config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME) +config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS) +config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) +config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE) +config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION) +config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE) +config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS) +config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# Incomplete features get their own specific disabling flags. This makes it +# easier to grep for target specific flags once the feature is complete. +config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FORMAT) +config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +if (LIBCXX_ABI_DEFINES) + set(abi_defines) + foreach (abi_define ${LIBCXX_ABI_DEFINES}) + if (NOT abi_define MATCHES "^_LIBCPP_ABI_") + message(SEND_ERROR "Invalid ABI macro ${abi_define} in LIBCXX_ABI_DEFINES") + endif() + list(APPEND abi_defines "#define ${abi_define}") + endforeach() + string(REPLACE ";" "\n" abi_defines "${abi_defines}") + config_define(${abi_defines} _LIBCPP_ABI_DEFINES) +endif() + +if (LIBCXX_EXTRA_SITE_DEFINES) + set(extra_site_defines) + foreach (extra_site_define ${LIBCXX_EXTRA_SITE_DEFINES}) + # Allow defines such as DEFINE=VAL, transformed into "#define DEFINE VAL". + string(REPLACE "=" " " extra_site_define "${extra_site_define}") + list(APPEND extra_site_defines "#define ${extra_site_define}") + endforeach() + string(REPLACE ";" "\n" extra_site_defines "${extra_site_defines}") + config_define(${extra_site_defines} _LIBCPP_EXTRA_SITE_DEFINES) +endif() # By default libc++ on Windows expects to use a shared library, which requires # the headers to use DLL import/export semantics. However when building a @@ -594,40 +939,56 @@ if (DEFINED WIN32 AND LIBCXX_ENABLE_STATIC AND NOT LIBCXX_ENABLE_SHARED) config_define(ON _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) endif() -if (LIBCXX_NEEDS_SITE_CONFIG) - configure_file("include/__config_site.in" - "${LIBCXX_BINARY_DIR}/__config_site" - @ONLY) - - # Provide the config definitions by included the generated __config_site - # file at compile time. - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") - add_compile_flags("/FI\"${LIBCXX_BINARY_DIR}/__config_site\"") - else() - add_compile_flags("-include ${LIBCXX_BINARY_DIR}/__config_site") - endif() +if (WIN32 AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY) + # If linking libcxxabi statically into libcxx, skip the dllimport attributes + # on symbols we refer to from libcxxabi. + add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) endif() +# Setup all common build flags ================================================= +function(cxx_add_common_build_flags target) + cxx_add_basic_build_flags(${target}) + cxx_add_warning_flags(${target}) + cxx_add_windows_flags(${target}) + cxx_add_exception_flags(${target}) + cxx_add_rtti_flags(${target}) + cxx_add_module_flags(${target}) + cxx_link_system_libraries(${target}) +endfunction() + #=============================================================================== # Setup Source Code And Tests #=============================================================================== -include_directories(include) -include_directories(${CMAKE_SOURCE_DIR}/src/libc/darwin) -include_directories(${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers) add_subdirectory(include) -add_subdirectory(lib) +add_subdirectory(src) +add_subdirectory(utils) +set(LIBCXX_TEST_DEPS "") + +if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) + list(APPEND LIBCXX_TEST_DEPS cxx_experimental) +endif() + +if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) + list(APPEND LIBCXX_TEST_DEPS cxx_external_threads) +endif() if (LIBCXX_INCLUDE_BENCHMARKS) add_subdirectory(benchmarks) endif() -# Create the lit.site.cfg file even when LIBCXX_INCLUDE_TESTS is OFF or -# LLVM_FOUND is OFF. This allows users to run the tests manually using -# LIT without requiring a full LLVM checkout. -add_subdirectory(test) if (LIBCXX_INCLUDE_TESTS) + add_subdirectory(test) add_subdirectory(lib/abi) + if (LIBCXX_STANDALONE_BUILD) + include(AddLLVM) # for get_llvm_lit_path + # Make sure the llvm-lit script is generated into the bin directory, and + # do it after adding all tests, since the generated script will only work + # correctly discovered tests against test locations from the source tree + # that have already been discovered. + add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit + ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit) + endif() endif() if (LIBCXX_INCLUDE_DOCS) diff --git a/CREDITS.TXT b/CREDITS.TXT index 46a06c6ea..cd5bc08a6 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -12,6 +12,13 @@ N: Saleem Abdulrasool E: compnerd@compnerd.org D: Minor patches and Linux fixes. +N: Ulf Adams +D: Invented the Ryu and Ryu Printf algorithms used in floating-point to_chars, and wrote the initial code. + +N: Muiez Ahmed +E: muiez@ibm.com +D: z/OS port. + N: Dan Albert E: danalbert@google.com D: Android support and test runner improvements. @@ -24,9 +31,8 @@ N: Holger Arnold E: holgerar@gmail.com D: Minor fix. -N: Ruben Van Boxem -E: vanboxem dot ruben at gmail dot com -D: Initial Windows patches. +N: Jorg Brown +D: Ported floating-point to_chars from MSVC to libc++. N: David Chisnall E: theraven at theravensnest dot org @@ -41,6 +47,15 @@ N: Jonathan B Coe E: jbcoe@me.com D: Implementation of propagate_const. +N: Matthew Dempsky +E: matthew@dempsky.org +D: Minor patches and bug fixes. + +N: Christopher Di Bella +E: cjdb@google.com +E: cjdb.ns@gmail.com +D: Library concepts. + N: Glen Joseph Fernandes E: glenjofe@gmail.com D: Implementation of to_address. @@ -53,10 +68,6 @@ N: Bill Fisher E: william.w.fisher@gmail.com D: Regex bug fixes. -N: Matthew Dempsky -E: matthew@dempsky.org -D: Minor patches and bug fixes. - N: Google Inc. D: Copyright owner and contributor of the CityHash algorithm @@ -64,6 +75,10 @@ N: Howard Hinnant E: hhinnant@apple.com D: Architect and primary author of libc++ +N: Sergej Jaskiewicz +E: jaskiewiczs@icloud.com +D: Minor improvements in the testing infrastructure + N: Hyeon-bin Jeong E: tuhertz@gmail.com D: Minor patches and bug fixes. @@ -72,6 +87,14 @@ N: Argyrios Kyrtzidis E: kyrtzidis@apple.com D: Bug fixes. +N: Stephan T. Lavavej +E: stl@microsoft.com +E: stl@nuwen.net +D: Implemented floating-point to_chars. + +N: Microsoft Corporation +D: Contributed floating-point to_chars. + N: Bruce Mitchener, Jr. E: bruce.mitchener@gmail.com D: Emscripten-related changes. @@ -104,6 +127,10 @@ N: Jon Roelofs E: jroelofS@jroelofs.com D: Remote testing, Newlib port, baremetal/single-threaded support. +N: Kent Ross +E: k@mad.cash +D: Patches for operator<=> support + N: Jonathan Sauer D: Minor patches, mostly related to constexpr @@ -122,6 +149,10 @@ N: Stephan Tolksdorf E: st@quanttec.com D: Minor fix +N: Ruben Van Boxem +E: vanboxem dot ruben at gmail dot com +D: Initial Windows patches. + N: Michael van der Westhuizen E: r1mikey at gmail dot com @@ -132,6 +163,11 @@ N: Klaas de Vries E: klaas at klaasgaaf dot nl D: Minor bug fix. +N: Mark de Wever +E: koraq at xs4all dot nl +D: Format library support. +D: Finalized the porting of MSVC's to_chars to libc++. + N: Zhang Xiongpang E: zhangxiongpang@gmail.com D: Minor patches and bug fixes. @@ -140,11 +176,11 @@ N: Xing Xue E: xingxue@ca.ibm.com D: AIX port -N: Zhihao Yuan -E: lichray@gmail.com -D: Standard compatibility fixes. - N: Jeffrey Yasskin E: jyasskin@gmail.com E: jyasskin@google.com D: Linux fixes. + +N: Zhihao Yuan +E: lichray@gmail.com +D: Standard compatibility fixes. diff --git a/NOTES.TXT b/NOTES.TXT deleted file mode 100644 index 24d245d43..000000000 --- a/NOTES.TXT +++ /dev/null @@ -1,29 +0,0 @@ -//===---------------------------------------------------------------------===// -// Notes relating to various libc++ tasks -//===---------------------------------------------------------------------===// - -This file contains notes about various libc++ tasks and processes. - -//===---------------------------------------------------------------------===// -// Post-Release TODO -//===---------------------------------------------------------------------===// - -These notes contain a list of things that must be done after branching for -an LLVM release. - -1. Update _LIBCPP_VERSION in `__config` -2. Update the __libcpp_version file. -3. Update the version number in `docs/conf.py` -4. Create ABI lists for the previous release under `lib/abi` - -//===---------------------------------------------------------------------===// -// Adding a new header TODO -//===---------------------------------------------------------------------===// - -These notes contain a list of things that must be done upon adding a new header -to libc++. - -1. Add a test under `test/libcxx` that the header defines `_LIBCPP_VERSION`. -2. Update `test/libcxx/double_include.sh.cpp` to include the new header. -3. Create a submodule in `include/module.modulemap` for the new header. -4. Update the include/CMakeLists.txt file to include the new header. diff --git a/TODO.TXT b/TODO.TXT index 652a38de7..bc785546b 100644 --- a/TODO.TXT +++ b/TODO.TXT @@ -2,7 +2,6 @@ This is meant to be a general place to list things that should be done "someday" CXX Runtime Library Tasks ========================= -* Fix that CMake always link to /usr/lib/libc++abi.dylib on OS X. * Look into mirroring libsupc++'s typeinfo vtable layout when libsupc++/libstdc++ is used as the runtime library. * Investigate and document interoperability between libc++ and libstdc++ on @@ -17,60 +16,8 @@ Test Suite Tasks * Improve the quality and portability of the locale test data. * Convert failure tests to use Clang Verify. -Filesystem Tasks -================ -* P0492r2 - Implement National body comments for Filesystem - * INCOMPLETE - US 25: has_filename() is equivalent to just !empty() - * INCOMPLETE - US 31: Everything is defined in terms of one implicit host system - * INCOMPLETE - US 32: Meaning of 27.10.2.1 unclear - * INCOMPLETE - US 33: Definition of canonical path problematic - * INCOMPLETE - US 34: Are there attributes of a file that are not an aspect of the file system? - * INCOMPLETE - US 35: What synchronization is required to avoid a file system race? - * INCOMPLETE - US 36: Symbolic links themselves are attached to a directory via (hard) links - * INCOMPLETE - US 37: The term “redundant current directory (dot) elements” is not defined - * INCOMPLETE - US 38: Duplicates §17.3.16 - * INCOMPLETE - US 39: Remove note: Dot and dot-dot are not directories - * INCOMPLETE - US 40: Not all directories have a parent. - * INCOMPLETE - US 41: The term “parent directory” for a (non-directory) file is unusual - * INCOMPLETE - US 42: Pathname resolution does not always resolve a symlink - * INCOMPLETE - US 43: Concerns about encoded character types - * INCOMPLETE - US 44: Definition of path in terms of a string requires leaky abstraction - * INCOMPLETE - US 45: Generic format portability compromised by unspecified root-name - * INCOMPLETE - US 46: filename can be empty so productions for relative-path are redundant - * INCOMPLETE - US 47: “.” and “..” already match the name production - * INCOMPLETE - US 48: Multiple separators are often meaningful in a root-name - * INCOMPLETE - US 49: What does “method of conversion method” mean? - * INCOMPLETE - US 50: 27.10.8.1 ¶ 1.4 largely redundant with ¶ 1.3 - * INCOMPLETE - US 51: Failing to add / when appending empty string prevents useful apps - * INCOMPLETE - US 52: remove_filename() postcondition is not by itself a definition - * INCOMPLETE - US 53: remove_filename()'s name does not correspond to its behavior - * INCOMPLETE - US 54: remove_filename() is broken - * INCOMPLETE - US 55: replace_extension()'s use of path as parameter is inappropriate - * INCOMPLETE - US 56: Remove replace_extension()'s conditional addition of period - * INCOMPLETE - US 57: On Windows, absolute paths will sort in among relative paths - * INCOMPLETE - US 58: parent_path() behavior for root paths is useless - * INCOMPLETE - US 59: filename() returning path for single path components is bizarre - * INCOMPLETE - US 60: path("/foo/").filename()==path(".") is surprising - * INCOMPLETE - US 61: Leading dots in filename() should not begin an extension - * INCOMPLETE - US 62: It is important that stem()+extension()==filename() - * INCOMPLETE - US 63: lexically_normal() inconsistently treats trailing "/" but not "/.." as directory - * INCOMPLETE - US 73, CA 2: root-name is effectively implementation defined - * INCOMPLETE - US 74, CA 3: The term “pathname” is ambiguous in some contexts - * INCOMPLETE - US 75, CA 4: Extra flag in path constructors is needed - * INCOMPLETE - US 76, CA 5: root-name definition is over-specified. - * INCOMPLETE - US 77, CA 6: operator/ and other appends not useful if arg has root-name - * INCOMPLETE - US 78, CA 7: Member absolute() in 27.10.4.1 is overspecified for non-POSIX-like O/S - * INCOMPLETE - US 79, CA 8: Some operation functions are overspecified for implementation-defined file types - * INCOMPLETE - US 185: Fold error_code and non-error_code signatures into one signature - * INCOMPLETE - FI 14: directory_entry comparisons are members - * INCOMPLETE - Late 36: permissions() error_code overload should be noexcept - * INCOMPLETE - Late 37: permissions() actions should be separate parameter - * INCOMPLETE - Late 42: resize_file() Postcondition missing argument - Misc Tasks ========== * Find all sequences of >2 underscores and eradicate them. * run clang-tidy on libc++ * Document the "conditionally-supported" bits of libc++ -* Look at basic_string's move assignment operator, re LWG 2063 and POCMA -* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447) diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 38c40c8f6..95e28618b 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -1,3 +1,14 @@ +if (CMAKE_VERSION VERSION_LESS 3.17) + message(WARNING "The libc++ benchmarks won't be available because the version of CMake is too old to support them.") + return() +endif() + +if (LIBCXX_STANDALONE_BUILD) + message(WARNING "The libc++ benchmarks are not available in a standalone build. Please migrate to an official build " + "as documented in https://libcxx.llvm.org/BuildingLibcxx.html.") + return() +endif() + include(ExternalProject) include(CheckCXXCompilerFlag) @@ -5,29 +16,32 @@ include(CheckCXXCompilerFlag) # Build Google Benchmark for libc++ #============================================================================== +set(CMAKE_FOLDER "${CMAKE_FOLDER}/Benchmarks") + set(BENCHMARK_LIBCXX_COMPILE_FLAGS -Wno-unused-command-line-argument -nostdinc++ - -isystem ${LIBCXX_SOURCE_DIR}/include + -isystem "${LIBCXX_GENERATED_INCLUDE_DIR}" -L${LIBCXX_LIBRARY_DIR} -Wl,-rpath,${LIBCXX_LIBRARY_DIR} ${SANITIZER_FLAGS} ) +if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS + -isystem "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}") +endif() if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH) list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -L${LIBCXX_CXX_ABI_LIBRARY_PATH} -Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH}) endif() -if (LIBCXX_NEEDS_SITE_CONFIG) - list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -include "${LIBCXX_BINARY_DIR}/__config_site") -endif() split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS) ExternalProject_Add(google-benchmark-libcxx EXCLUDE_FROM_ALL ON DEPENDS cxx cxx-headers PREFIX benchmark-libcxx - SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark + SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} @@ -44,7 +58,7 @@ ExternalProject_Add(google-benchmark-libcxx set(BENCHMARK_NATIVE_TARGET_FLAGS) if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN) set(BENCHMARK_NATIVE_TARGET_FLAGS - -gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) + --gcc-toolchain=${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) endif() split_list(BENCHMARK_NATIVE_TARGET_FLAGS) @@ -52,7 +66,7 @@ if (LIBCXX_BENCHMARK_NATIVE_STDLIB) ExternalProject_Add(google-benchmark-native EXCLUDE_FROM_ALL ON PREFIX benchmark-native - SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark + SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} @@ -72,67 +86,43 @@ set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx) set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native) -check_flag_supported("-std=c++17") -mangle_name("LIBCXX_SUPPORTS_STD_EQ_c++17_FLAG" BENCHMARK_SUPPORTS_STD_CXX17_FLAG) -if (${BENCHMARK_SUPPORTS_STD_CXX17_FLAG}) - set(BENCHMARK_DIALECT_FLAG "-std=c++17") -else() - # If the compiler doesn't support -std=c++17, attempt to fall back to -std=c++1z while still - # requiring C++17 language features. - set(BENCHMARK_DIALECT_FLAG "-std=c++1z") -endif() - -set(BENCHMARK_TEST_COMPILE_FLAGS - ${BENCHMARK_DIALECT_FLAG} -O2 - -fsized-deallocation - -I${BENCHMARK_LIBCXX_INSTALL}/include - -I${LIBCXX_SOURCE_DIR}/test/support -) -set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS - -nostdinc++ - -isystem ${LIBCXX_SOURCE_DIR}/include - ${BENCHMARK_TEST_COMPILE_FLAGS} - ${SANITIZER_FLAGS} - -Wno-user-defined-literals -) - -set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS - -nodefaultlibs - -L${BENCHMARK_LIBCXX_INSTALL}/lib/ - ${SANITIZER_FLAGS} -) -set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS - ${BENCHMARK_NATIVE_TARGET_FLAGS} - ${BENCHMARK_TEST_COMPILE_FLAGS} -) -set(BENCHMARK_TEST_NATIVE_LINK_FLAGS - ${BENCHMARK_NATIVE_TARGET_FLAGS} - -L${BENCHMARK_NATIVE_INSTALL}/lib -) -split_list(BENCHMARK_TEST_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS) -split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS) +add_library( cxx-benchmarks-flags INTERFACE) +target_compile_features( cxx-benchmarks-flags INTERFACE cxx_std_20) +target_compile_options( cxx-benchmarks-flags INTERFACE -O2 -fsized-deallocation -nostdinc++) +target_include_directories(cxx-benchmarks-flags INTERFACE "${LIBCXX_GENERATED_INCLUDE_DIR}" + INTERFACE "${BENCHMARK_LIBCXX_INSTALL}/include" + INTERFACE "${LIBCXX_SOURCE_DIR}/test/support") +add_library( cxx-benchmarks-flags-native INTERFACE) +target_link_libraries( cxx-benchmarks-flags-native INTERFACE cxx-benchmarks-flags) +target_compile_options(cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS}) +target_link_options( cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS} "-L${BENCHMARK_NATIVE_INSTALL}/lib") if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN} PATH_SUFFIXES lib lib64 DOC "The libstdc++ filesystem library used by the benchmarks" ) - if (NOT "${LIBSTDCXX_FILESYSTEM_TEST}" STREQUAL "LIBSTDCXX_FILESYSTEM_TEST-NOTFOUND") - set(LIBSTDCXX_FILESYSTEM_LIB "stdc++fs") - endif() + if (LIBSTDCXX_FILESYSTEM_TEST) + target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lstdc++fs) + endif() +else() + target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lc++fs -lc++experimental) endif() +add_library( cxx-benchmarks-flags-libcxx INTERFACE) +target_link_libraries( cxx-benchmarks-flags-libcxx INTERFACE cxx-benchmarks-flags) +target_compile_options(cxx-benchmarks-flags-libcxx INTERFACE ${SANITIZER_FLAGS} -Wno-user-defined-literals -Wno-suggest-override) +target_link_options( cxx-benchmarks-flags-libcxx INTERFACE -nodefaultlibs "-L${BENCHMARK_LIBCXX_INSTALL}/lib" ${SANITIZER_FLAGS}) + set(libcxx_benchmark_targets) function(add_benchmark_test name source_file) set(libcxx_target ${name}_libcxx) list(APPEND libcxx_benchmark_targets ${libcxx_target}) add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file}) - add_dependencies(${libcxx_target} cxx cxx-headers google-benchmark-libcxx) + target_link_libraries(${libcxx_target} PRIVATE cxx-benchmarks-flags-libcxx) + add_dependencies(${libcxx_target} cxx google-benchmark-libcxx) add_dependencies(cxx-benchmarks ${libcxx_target}) if (LIBCXX_ENABLE_SHARED) target_link_libraries(${libcxx_target} PRIVATE cxx_shared) @@ -150,24 +140,15 @@ function(add_benchmark_test name source_file) PROPERTIES OUTPUT_NAME "${name}.libcxx.out" RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" - COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}" - LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}") + CXX_EXTENSIONS NO) cxx_link_system_libraries(${libcxx_target}) if (LIBCXX_BENCHMARK_NATIVE_STDLIB) - if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++" AND NOT DEFINED LIBSTDCXX_FILESYSTEM_LIB - AND "${name}" STREQUAL "filesystem") - return() - endif() set(native_target ${name}_native) add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file}) + target_link_libraries(${native_target} PRIVATE cxx-benchmarks-flags-native) add_dependencies(${native_target} google-benchmark-native google-benchmark-libcxx) target_link_libraries(${native_target} PRIVATE -lbenchmark) - if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") - target_link_libraries(${native_target} PRIVATE ${LIBSTDCXX_FILESYSTEM_LIB}) - elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++") - target_link_libraries(${native_target} PRIVATE -lc++fs -lc++experimental) - endif() if (LIBCXX_HAS_PTHREAD_LIB) target_link_libraries(${native_target} PRIVATE -pthread) endif() @@ -176,9 +157,7 @@ function(add_benchmark_test name source_file) PROPERTIES OUTPUT_NAME "${name}.native.out" RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" - INCLUDE_DIRECTORIES "" - COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}" - LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}") + CXX_EXTENSIONS NO) endif() endfunction() @@ -187,6 +166,11 @@ endfunction() # Register Benchmark tests #============================================================================== file(GLOB BENCHMARK_TESTS "*.bench.cpp") + +if (NOT LIBCXX_ENABLE_INCOMPLETE_FEATURES) + list(FILTER BENCHMARK_TESTS EXCLUDE REGEX "(format_to_n|format_to|format|formatted_size|formatter_float|std_format_spec_string_unicode).bench.cpp") +endif() + foreach(test_path ${BENCHMARK_TESTS}) get_filename_component(test_file "${test_path}" NAME) string(REPLACE ".bench.cpp" "" test_name "${test_file}") @@ -217,4 +201,3 @@ if (LIBCXX_INCLUDE_TESTS) DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS} ARGS ${BENCHMARK_LIT_ARGS}) endif() - diff --git a/benchmarks/CartesianBenchmarks.h b/benchmarks/CartesianBenchmarks.h index 89b6d854b..2eea15681 100644 --- a/benchmarks/CartesianBenchmarks.h +++ b/benchmarks/CartesianBenchmarks.h @@ -131,4 +131,3 @@ TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) { if (opaque) benchmark::DoNotOptimize(value); return value; } - diff --git a/benchmarks/GenerateInput.h b/benchmarks/GenerateInput.h index e4f131c62..3e63f8413 100644 --- a/benchmarks/GenerateInput.h +++ b/benchmarks/GenerateInput.h @@ -36,10 +36,9 @@ inline char getRandomChar() { } template -inline IntT getRandomInteger(IntT Min = 0, - IntT Max = std::numeric_limits::max()) { - std::uniform_int_distribution dist(Min, Max); - return dist(getRandomEngine()); +inline IntT getRandomInteger(IntT Min, IntT Max) { + std::uniform_int_distribution dist(Min, Max); + return static_cast(dist(getRandomEngine())); } inline std::string getRandomString(std::size_t Len) { @@ -102,7 +101,7 @@ template std::vector getRandomIntegerInputs(size_t N) { std::vector inputs; for (size_t i=0; i < N; ++i) { - inputs.push_back(getRandomInteger()); + inputs.push_back(getRandomInteger(0, std::numeric_limits::max())); } return inputs; } diff --git a/benchmarks/VariantBenchmarks.h b/benchmarks/VariantBenchmarks.h new file mode 100644 index 000000000..2feaeab51 --- /dev/null +++ b/benchmarks/VariantBenchmarks.h @@ -0,0 +1,58 @@ +// -*- 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 BENCHMARK_VARIANT_BENCHMARKS_H +#define BENCHMARK_VARIANT_BENCHMARKS_H + +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +#include "GenerateInput.h" + +namespace VariantBenchmarks { + +template +struct S { + static constexpr size_t v = I; +}; + +template +static auto genVariants(std::index_sequence) { + using V = std::variant...>; + using F = V (*)(); + static constexpr F fs[] = {[] { return V(std::in_place_index); }...}; + + std::array result = {}; + for (auto& v : result) { + v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)](); + } + + return result; +} + +template +static void BM_Visit(benchmark::State& state) { + auto args = genVariants(std::make_index_sequence{}); + for (auto _ : state) { + benchmark::DoNotOptimize(std::apply( + [](auto... vs) { + return std::visit([](auto... is) { return (is.v + ... + 0); }, vs...); + }, + args)); + } +} + +} // end namespace VariantBenchmarks + +#endif // BENCHMARK_VARIANT_BENCHMARKS_H diff --git a/benchmarks/algorithms.bench.cpp b/benchmarks/algorithms.bench.cpp index b259d4764..e5dd37f06 100644 --- a/benchmarks/algorithms.bench.cpp +++ b/benchmarks/algorithms.bench.cpp @@ -14,14 +14,23 @@ namespace { -enum class ValueType { Uint32, String }; -struct AllValueTypes : EnumValuesAsTuple { - static constexpr const char* Names[] = {"uint32", "string"}; +enum class ValueType { Uint32, Uint64, Pair, Tuple, String }; +struct AllValueTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = { + "uint32", "uint64", "pair", + "tuple", "string"}; }; template -using Value = - std::conditional_t; +using Value = std::conditional_t< + V() == ValueType::Uint32, uint32_t, + std::conditional_t< + V() == ValueType::Uint64, uint64_t, + std::conditional_t< + V() == ValueType::Pair, std::pair, + std::conditional_t, + std::string> > > >; enum class Order { Random, @@ -29,30 +38,114 @@ enum class Order { Descending, SingleElement, PipeOrgan, - Heap + Heap, + QuickSortAdversary, }; -struct AllOrders : EnumValuesAsTuple { +struct AllOrders : EnumValuesAsTuple { static constexpr const char* Names[] = {"Random", "Ascending", "Descending", "SingleElement", - "PipeOrgan", "Heap"}; + "PipeOrgan", "Heap", + "QuickSortAdversary"}; }; -void fillValues(std::vector& V, size_t N, Order O) { +// fillAdversarialQuickSortInput fills the input vector with N int-like values. +// These values are arranged in such a way that they would invoke O(N^2) +// behavior on any quick sort implementation that satisifies certain conditions. +// Details are available in the following paper: +// "A Killer Adversary for Quicksort", M. D. McIlroy, Software—Practice & +// ExperienceVolume 29 Issue 4 April 10, 1999 pp 341–344. +// https://dl.acm.org/doi/10.5555/311868.311871. +template +void fillAdversarialQuickSortInput(T& V, size_t N) { + assert(N > 0); + // If an element is equal to gas, it indicates that the value of the element + // is still to be decided and may change over the course of time. + const int gas = N - 1; + V.resize(N); + for (int i = 0; i < N; ++i) { + V[i] = gas; + } + // Candidate for the pivot position. + int candidate = 0; + int nsolid = 0; + // Populate all positions in the generated input to gas. + std::vector ascVals(V.size()); + // Fill up with ascending values from 0 to V.size()-1. These will act as + // indices into V. + std::iota(ascVals.begin(), ascVals.end(), 0); + std::sort(ascVals.begin(), ascVals.end(), [&](int x, int y) { + if (V[x] == gas && V[y] == gas) { + // We are comparing two inputs whose value is still to be decided. + if (x == candidate) { + V[x] = nsolid++; + } else { + V[y] = nsolid++; + } + } + if (V[x] == gas) { + candidate = x; + } else if (V[y] == gas) { + candidate = y; + } + return V[x] < V[y]; + }); +} + +template +void fillValues(std::vector& V, size_t N, Order O) { if (O == Order::SingleElement) { V.resize(N, 0); + } else if (O == Order::QuickSortAdversary) { + fillAdversarialQuickSortInput(V, N); } else { while (V.size() < N) V.push_back(V.size()); } } -void fillValues(std::vector& V, size_t N, Order O) { - +template +void fillValues(std::vector >& V, size_t N, Order O) { if (O == Order::SingleElement) { - V.resize(N, getRandomString(1024)); + V.resize(N, std::make_pair(0, 0)); } else { while (V.size() < N) - V.push_back(getRandomString(1024)); + // Half of array will have the same first element. + if (V.size() % 2) { + V.push_back(std::make_pair(V.size(), V.size())); + } else { + V.push_back(std::make_pair(0, V.size())); + } + } +} + +template +void fillValues(std::vector >& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, std::make_tuple(0, 0, 0)); + } else { + while (V.size() < N) + // One third of array will have the same first element. + // One third of array will have the same first element and the same second element. + switch (V.size() % 3) { + case 0: + V.push_back(std::make_tuple(V.size(), V.size(), V.size())); + break; + case 1: + V.push_back(std::make_tuple(0, V.size(), V.size())); + break; + case 2: + V.push_back(std::make_tuple(0, 0, V.size())); + break; + } + } +} + +void fillValues(std::vector& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, getRandomString(64)); + } else { + while (V.size() < N) + V.push_back(getRandomString(64)); } } @@ -82,24 +175,30 @@ void sortValues(T& V, Order O) { case Order::Heap: std::make_heap(V.begin(), V.end()); break; + case Order::QuickSortAdversary: + // Nothing to do + break; } } +constexpr size_t TestSetElements = +#if !TEST_HAS_FEATURE(memory_sanitizer) + 1 << 18; +#else + 1 << 14; +#endif + template std::vector > > makeOrderedValues(size_t N, Order O) { - // Let's make sure that all random sequences of the same size are the same. - // That way we can compare the different algorithms with the same input. - static std::map, std::vector > > - Cached; - - auto& Values = Cached[{N, O}]; - if (Values.empty()) { - fillValues(Values, N, O); - sortValues(Values, O); - }; - const size_t NumCopies = std::max(size_t{1}, 1000 / N); - return { NumCopies, Values }; + std::vector > > Ret; + const size_t NumCopies = std::max(size_t{1}, TestSetElements / N); + Ret.resize(NumCopies); + for (auto& V : Ret) { + fillValues(V, N, O); + sortValues(V, O); + } + return Ret; } template @@ -111,19 +210,28 @@ TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies, state.ResumeTiming(); } +enum class BatchSize { + CountElements, + CountBatch, +}; + template void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O, - bool CountElements, F f) { + BatchSize Count, F Body) { auto Copies = makeOrderedValues(Quantity, O); - const auto Orig = Copies[0]; + auto Orig = Copies; - const size_t Batch = CountElements ? Copies.size() * Quantity : Copies.size(); + const size_t Batch = Count == BatchSize::CountElements + ? Copies.size() * Quantity + : Copies.size(); while (state.KeepRunningBatch(Batch)) { for (auto& Copy : Copies) { - f(Copy); + Body(Copy); benchmark::DoNotOptimize(Copy); } - resetCopies(state, Copies, Orig); + state.PauseTiming(); + Copies = Orig; + state.ResumeTiming(); } } @@ -132,9 +240,9 @@ struct Sort { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), false, [](auto& Copy) { - std::sort(Copy.begin(), Copy.end()); - }); + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); }); } bool skip() const { return Order() == ::Order::Heap; } @@ -150,9 +258,9 @@ struct StableSort { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), false, [](auto& Copy) { - std::stable_sort(Copy.begin(), Copy.end()); - }); + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); }); } bool skip() const { return Order() == ::Order::Heap; } @@ -168,9 +276,9 @@ struct MakeHeap { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), false, [](auto& Copy) { - std::make_heap(Copy.begin(), Copy.end()); - }); + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); }); } std::string name() const { @@ -185,7 +293,7 @@ struct SortHeap { void run(benchmark::State& state) const { runOpOnCopies( - state, Quantity, Order::Heap, false, + state, Quantity, Order::Heap, BatchSize::CountElements, [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); }); } @@ -199,10 +307,11 @@ struct MakeThenSortHeap { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), false, [](auto& Copy) { - std::make_heap(Copy.begin(), Copy.end()); - std::sort_heap(Copy.begin(), Copy.end()); - }); + runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { + std::make_heap(Copy.begin(), Copy.end()); + std::sort_heap(Copy.begin(), Copy.end()); + }); } std::string name() const { @@ -216,11 +325,12 @@ struct PushHeap { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), true, [](auto& Copy) { - for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) { - std::push_heap(Copy.begin(), I + 1); - } - }); + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) { + std::push_heap(Copy.begin(), I + 1); + } + }); } bool skip() const { return Order() == ::Order::Heap; } @@ -236,11 +346,12 @@ struct PopHeap { size_t Quantity; void run(benchmark::State& state) const { - runOpOnCopies(state, Quantity, Order(), true, [](auto& Copy) { - for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) { - std::pop_heap(B, I); - } - }); + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) { + std::pop_heap(B, I); + } + }); } std::string name() const { diff --git a/benchmarks/algorithms.partition_point.bench.cpp b/benchmarks/algorithms.partition_point.bench.cpp index 840cf0391..8192f9720 100644 --- a/benchmarks/algorithms.partition_point.bench.cpp +++ b/benchmarks/algorithms.partition_point.bench.cpp @@ -30,7 +30,7 @@ struct TestIntBase { static std::vector generateInput(size_t size) { std::vector Res(size); std::generate(Res.begin(), Res.end(), - [] { return getRandomInteger(); }); + [] { return getRandomInteger(0, std::numeric_limits::max()); }); return Res; } }; diff --git a/benchmarks/allocation.bench.cpp b/benchmarks/allocation.bench.cpp index 236e74044..ad962de5b 100644 --- a/benchmarks/allocation.bench.cpp +++ b/benchmarks/allocation.bench.cpp @@ -97,7 +97,6 @@ static void BM_DeallocateOnly(benchmark::State& st) { const size_t alloc_size = st.range(0); const auto NumAllocs = st.max_iterations; - using PtrT = void*; std::vector Pointers(NumAllocs); for (auto& p : Pointers) { p = AllocWrapper::Allocate(alloc_size); diff --git a/benchmarks/deque.bench.cpp b/benchmarks/deque.bench.cpp index 0025a335c..61b45cbf4 100644 --- a/benchmarks/deque.bench.cpp +++ b/benchmarks/deque.bench.cpp @@ -1,4 +1,3 @@ -// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/benchmarks/filesystem.bench.cpp b/benchmarks/filesystem.bench.cpp index 64314ac5a..4fe4fc503 100644 --- a/benchmarks/filesystem.bench.cpp +++ b/benchmarks/filesystem.bench.cpp @@ -62,7 +62,7 @@ void BM_PathConstructIter(benchmark::State &st, GenInputs gen) { } template void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) { - BM_PathConstructIter(st, gen); + BM_PathConstructIter(st, gen); } template void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) { @@ -83,7 +83,7 @@ void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) { PP /= Part; benchmark::DoNotOptimize(PP.native().data()); while (st.KeepRunning()) { - for (auto &E : PP) { + for (auto const& E : PP) { benchmark::DoNotOptimize(E.native().data()); } benchmark::ClobberMemory(); @@ -104,7 +104,7 @@ void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) { benchmark::DoNotOptimize(PP.native().data()); while (st.KeepRunning()) { const path P = PP.native(); - for (auto &E : P) { + for (auto const& E : P) { benchmark::DoNotOptimize(E.native().data()); } benchmark::ClobberMemory(); diff --git a/benchmarks/format.bench.cpp b/benchmarks/format.bench.cpp new file mode 100644 index 000000000..89f113253 --- /dev/null +++ b/benchmarks/format.bench.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +#include + +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +template +static void BM_format_string(benchmark::State& state) { + size_t size = state.range(0); + std::basic_string str(size, CharT('*')); + + while (state.KeepRunningBatch(str.size())) + benchmark::DoNotOptimize(std::format(CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} +BENCHMARK_TEMPLATE(BM_format_string, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/format_to.bench.cpp b/benchmarks/format_to.bench.cpp new file mode 100644 index 000000000..4d6489786 --- /dev/null +++ b/benchmarks/format_to.bench.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +/*** Back inserter ***/ + +template +static void BM_format_to_string_back_inserter(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + for (auto _ : state) { + Container output; + benchmark::DoNotOptimize(std::format_to(std::back_inserter(output), CSTR("{}"), str)); + } + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Begin ***/ + +template +static void BM_format_to_string_begin(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + Container output(size, CharT('-')); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Pointer ***/ + +template +static void BM_format_to_string_span(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + std::span output{buffer}; + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +template +static void BM_format_to_string_pointer(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + CharT* output = buffer.data(); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(output, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Main ***/ + +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20); + +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/format_to_n.bench.cpp b/benchmarks/format_to_n.bench.cpp new file mode 100644 index 000000000..c1e52b010 --- /dev/null +++ b/benchmarks/format_to_n.bench.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +/*** Back inserter ***/ + +template +static void BM_format_to_n_string_back_inserter(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + for (auto _ : state) { + Container output; + benchmark::DoNotOptimize(std::format_to_n(std::back_inserter(output), size, CSTR("{}"), str)); + } + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Begin ***/ + +template +static void BM_format_to_n_string_begin(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + Container output(size, CharT('-')); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Pointer ***/ + +template +static void BM_format_to_n_string_span(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + std::span output{buffer}; + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +template +static void BM_format_to_n_string_pointer(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + CharT* output = buffer.data(); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(output, size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Main ***/ + +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20); + +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/formatted_size.bench.cpp b/benchmarks/formatted_size.bench.cpp new file mode 100644 index 000000000..de67dae71 --- /dev/null +++ b/benchmarks/formatted_size.bench.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +#include + +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +template +static void BM_formatted_size_string(benchmark::State& state) { + size_t size = state.range(0); + std::basic_string str(size, CharT('*')); + + while (state.KeepRunningBatch(str.size())) + benchmark::DoNotOptimize(std::formatted_size(CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} +BENCHMARK_TEMPLATE(BM_formatted_size_string, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_formatted_size_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/formatter_float.bench.cpp b/benchmarks/formatter_float.bench.cpp new file mode 100644 index 000000000..3190b3779 --- /dev/null +++ b/benchmarks/formatter_float.bench.cpp @@ -0,0 +1,241 @@ +//===----------------------------------------------------------------------===// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include +#include +#include +#include + +#include "CartesianBenchmarks.h" +#include "benchmark/benchmark.h" + +// *** Localization *** +enum class LocalizationE { False, True }; +struct AllLocalizations : EnumValuesAsTuple { + static constexpr const char* Names[] = {"LocFalse", "LocTrue"}; +}; + +template +struct Localization {}; + +template <> +struct Localization { + static constexpr const char* fmt = ""; +}; + +template <> +struct Localization { + static constexpr const char* fmt = "L"; +}; + +// *** Types *** +enum class TypeE { Float, Double, LongDouble }; +// TODO FMT Set to 3 after to_chars has long double suport. +struct AllTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Float", "Double", "LongDouble"}; +}; + +template +struct Type {}; + +template <> +struct Type { + using type = float; +}; + +template <> +struct Type { + using type = double; +}; + +template <> +struct Type { + using type = long double; +}; + +// *** Values *** +enum class ValueE { Inf, Random }; +struct AllValues : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Inf", "Random"}; +}; + +template +struct Value {}; + +template <> +struct Value { + template + static std::array make_data() { + std::array result; + std::fill(result.begin(), result.end(), -std::numeric_limits::infinity()); + return result; + } +}; + +template <> +struct Value { + template + static std::array make_data() { + std::random_device seed; + std::mt19937 generator(seed()); + std::uniform_int_distribution> distribution; + + std::array result; + std::generate(result.begin(), result.end(), [&] { + while (true) { + auto result = std::bit_cast(distribution(generator)); + if (std::isfinite(result)) + return result; + } + }); + return result; + } +}; + +// *** Display Type *** +enum class DisplayTypeE { + Default, + Hex, + Scientific, + Fixed, + General, +}; +struct AllDisplayTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"DisplayDefault", "DisplayHex", "DisplayScientific", "DisplayFixed", + "DisplayGeneral"}; +}; + +template +struct DisplayType {}; + +template <> +struct DisplayType { + static constexpr const char* fmt = ""; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "a"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "e"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "f"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "g"; +}; + +// *** Alignment *** +enum class AlignmentE { None, Left, Center, Right, ZeroPadding }; +struct AllAlignments : EnumValuesAsTuple { + static constexpr const char* Names[] = {"AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight", + "ZeroPadding"}; +}; + +template +struct Alignment {}; + +template <> +struct Alignment { + static constexpr const char* fmt = ""; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0<17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0^17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0>17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "017500"; +}; + +enum class PrecisionE { None, Zero, Small, Huge }; +struct AllPrecisions : EnumValuesAsTuple { + static constexpr const char* Names[] = {"PrecNone", "PrecZero", "PrecSmall", "PrecHuge"}; +}; + +template +struct Precision {}; + +template <> +struct Precision { + static constexpr const char* fmt = ""; +}; + +template <> +struct Precision { + static constexpr const char* fmt = ".0"; +}; + +template <> +struct Precision { + static constexpr const char* fmt = ".10"; +}; + +template <> +struct Precision { + // The maximum precision for a minimal sub normal long double is ±0x1p-16494. + // This value is always larger than that value forcing the trailing zero path + // to be executed. + static constexpr const char* fmt = ".17000"; +}; + +template +struct FloatingPoint { + using F = typename Type::type; + + void run(benchmark::State& state) const { + std::array data{Value::template make_data()}; + std::array output; + std::string fmt{std::string("{:") + Alignment::fmt + Precision::fmt + + Localization::fmt + DisplayType::fmt + "}"}; + + while (state.KeepRunningBatch(1000)) + for (F value : data) + benchmark::DoNotOptimize(std::format_to(output.begin(), fmt, value)); + } + + std::string name() const { + return "FloatingPoint" + L::name() + DT::name() + T::name() + V::name() + A::name() + P::name(); + } +}; + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + makeCartesianProductBenchmark(); + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/map.bench.cpp b/benchmarks/map.bench.cpp new file mode 100644 index 000000000..dd1884f65 --- /dev/null +++ b/benchmarks/map.bench.cpp @@ -0,0 +1,1037 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include + +#include "CartesianBenchmarks.h" +#include "benchmark/benchmark.h" +#include "test_macros.h" + +// When VALIDATE is defined the benchmark will run to validate the benchmarks. +// The time taken by several operations depend on whether or not an element +// exists. To avoid errors in the benchmark these operations have a validation +// mode to test the benchmark. Since they are not meant to be benchmarked the +// number of sizes tested is limited to 1. +//#define VALIDATE + +namespace { + +enum class Mode { Hit, Miss }; + +struct AllModes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"ExistingElement", "NewElement"}; +}; + +// The positions of the hints to pick: +// - Begin picks the first item. The item cannot be put before this element. +// - Thrid picks the third item. This is just an element with a valid entry +// before and after it. +// - Correct contains the correct hint. +// - End contains a hint to the end of the map. +enum class Hint { Begin, Third, Correct, End }; +struct AllHints : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Begin", "Third", "Correct", "End"}; +}; + +enum class Order { Sorted, Random }; +struct AllOrders : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Sorted", "Random"}; +}; + +struct TestSets { + std::vector Keys; + std::vector > Maps; + std::vector< + std::vector::const_iterator> > + Hints; +}; + +enum class Shuffle { None, Keys, Hints }; + +TestSets makeTestingSets(size_t MapSize, Mode mode, Shuffle shuffle, + size_t max_maps) { + /* + * The shuffle does not retain the random number generator to use the same + * set of random numbers for every iteration. + */ + TestSets R; + + int MapCount = std::min(max_maps, 1000000 / MapSize); + + for (uint64_t I = 0; I < MapSize; ++I) { + R.Keys.push_back(mode == Mode::Hit ? 2 * I + 2 : 2 * I + 1); + } + if (shuffle == Shuffle::Keys) + std::shuffle(R.Keys.begin(), R.Keys.end(), std::mt19937()); + + for (int M = 0; M < MapCount; ++M) { + auto& map = R.Maps.emplace_back(); + auto& hints = R.Hints.emplace_back(); + for (uint64_t I = 0; I < MapSize; ++I) { + hints.push_back(map.insert(std::make_pair(2 * I + 2, 0)).first); + } + if (shuffle == Shuffle::Hints) + std::shuffle(hints.begin(), hints.end(), std::mt19937()); + } + + return R; +} + +struct Base { + size_t MapSize; + Base(size_t T) : MapSize(T) {} + + std::string baseName() const { return "_MapSize=" + std::to_string(MapSize); } +}; + +//*******************************************************************| +// Member functions | +//*******************************************************************| + +struct ConstructorDefault { + void run(benchmark::State& State) const { + for (auto _ : State) { + benchmark::DoNotOptimize(std::map()); + } + } + + std::string name() const { return "BM_ConstructorDefault"; } +}; + +struct ConstructorIterator : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { +#ifndef VALIDATE + benchmark::DoNotOptimize( + std::map(Map.begin(), Map.end())); +#else + std::map M{Map.begin(), Map.end()}; + if (M != Map) + State.SkipWithError("Map copy not identical"); +#endif + } + } + + std::string name() const { return "BM_ConstructorIterator" + baseName(); } +}; + +struct ConstructorCopy : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { +#ifndef VALIDATE + std::map M(Map); + benchmark::DoNotOptimize(M); +#else + std::map M(Map); + if (M != Map) + State.SkipWithError("Map copy not identical"); +#endif + } + } + + std::string name() const { return "BM_ConstructorCopy" + baseName(); } +}; + +struct ConstructorMove : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + std::map M(std::move(Map)); + benchmark::DoNotOptimize(M); + } + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + std::string name() const { return "BM_ConstructorMove" + baseName(); } +}; + +//*******************************************************************| +// Capacity | +//*******************************************************************| + +struct Empty : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1); + auto& Map = Data.Maps.front(); + for (auto _ : State) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.empty()); +#else + if (Map.empty()) + State.SkipWithError("Map contains an invalid number of elements."); +#endif + } + } + + std::string name() const { return "BM_Empty" + baseName(); } +}; + +struct Size : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1); + auto& Map = Data.Maps.front(); + for (auto _ : State) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.size()); +#else + if (Map.size() != MapSize) + State.SkipWithError("Map contains an invalid number of elements."); +#endif + } + } + + std::string name() const { return "BM_Size" + baseName(); } +}; + +//*******************************************************************| +// Modifiers | +//*******************************************************************| + +struct Clear : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + Map.clear(); + benchmark::DoNotOptimize(Map); + } + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + std::string name() const { return "BM_Clear" + baseName(); } +}; + +template +struct Insert : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert(std::make_pair(K, 1))); +#else + bool Inserted = Map.insert(std::make_pair(K, 1)).second; + if (Mode() == ::Mode::Hit) { + if (Inserted) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (!Inserted) + State.SkipWithError("Failed to insert e new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_Insert" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct InsertHint : Base { + using Base::Base; + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto H = Data.Hints[I].begin(); + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert(*H, std::make_pair(K, 1))); +#else + auto Inserted = Map.insert(*H, std::make_pair(K, 1)); + if (Mode() == ::Mode::Hit) { + if (Inserted != *H) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (++Inserted != *H) + State.SkipWithError("Failed to insert a new element"); + } +#endif + ++H; + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto Third = *(Data.Hints[I].begin() + 2); + for (auto K : Data.Keys) { + auto Itor = hint == ::Hint::Begin + ? Map.begin() + : hint == ::Hint::Third ? Third : Map.end(); +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert(Itor, std::make_pair(K, 1))); +#else + size_t Size = Map.size(); + Map.insert(Itor, std::make_pair(K, 1)); + if (Mode() == ::Mode::Hit) { + if (Size != Map.size()) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (Size + 1 != Map.size()) + State.SkipWithError("Failed to insert a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + void run(benchmark::State& State) const { + static constexpr auto h = Hint(); + run(State); + } + + std::string name() const { + return "BM_InsertHint" + baseName() + Mode::name() + Hint::name(); + } +}; + +template +struct InsertAssign : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert_or_assign(K, 1)); +#else + bool Inserted = Map.insert_or_assign(K, 1).second; + if (Mode() == ::Mode::Hit) { + if (Inserted) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (!Inserted) + State.SkipWithError("Failed to insert e new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_InsertAssign" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct InsertAssignHint : Base { + using Base::Base; + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto H = Data.Hints[I].begin(); + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert_or_assign(*H, K, 1)); +#else + auto Inserted = Map.insert_or_assign(*H, K, 1); + if (Mode() == ::Mode::Hit) { + if (Inserted != *H) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (++Inserted != *H) + State.SkipWithError("Failed to insert a new element"); + } +#endif + ++H; + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto Third = *(Data.Hints[I].begin() + 2); + for (auto K : Data.Keys) { + auto Itor = hint == ::Hint::Begin + ? Map.begin() + : hint == ::Hint::Third ? Third : Map.end(); +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.insert_or_assign(Itor, K, 1)); +#else + size_t Size = Map.size(); + Map.insert_or_assign(Itor, K, 1); + if (Mode() == ::Mode::Hit) { + if (Size != Map.size()) + State.SkipWithError("Inserted a duplicate element"); + } else { + if (Size + 1 != Map.size()) + State.SkipWithError("Failed to insert a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + void run(benchmark::State& State) const { + static constexpr auto h = Hint(); + run(State); + } + + std::string name() const { + return "BM_InsertAssignHint" + baseName() + Mode::name() + Hint::name(); + } +}; + +template +struct Emplace : Base { + using Base::Base; + + void run(benchmark::State& State) const { + + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.emplace(K, 1)); +#else + bool Inserted = Map.emplace(K, 1).second; + if (Mode() == ::Mode::Hit) { + if (Inserted) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (!Inserted) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_Emplace" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct EmplaceHint : Base { + using Base::Base; + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto H = Data.Hints[I].begin(); + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.emplace_hint(*H, K, 1)); +#else + auto Inserted = Map.emplace_hint(*H, K, 1); + if (Mode() == ::Mode::Hit) { + if (Inserted != *H) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (++Inserted != *H) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + ++H; + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto Third = *(Data.Hints[I].begin() + 2); + for (auto K : Data.Keys) { + auto Itor = hint == ::Hint::Begin + ? Map.begin() + : hint == ::Hint::Third ? Third : Map.end(); +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.emplace_hint(Itor, K, 1)); +#else + size_t Size = Map.size(); + Map.emplace_hint(Itor, K, 1); + if (Mode() == ::Mode::Hit) { + if (Size != Map.size()) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (Size + 1 != Map.size()) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + void run(benchmark::State& State) const { + static constexpr auto h = Hint(); + run(State); + } + + std::string name() const { + return "BM_EmplaceHint" + baseName() + Mode::name() + Hint::name(); + } +}; + +template +struct TryEmplace : Base { + using Base::Base; + + void run(benchmark::State& State) const { + + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.try_emplace(K, 1)); +#else + bool Inserted = Map.try_emplace(K, 1).second; + if (Mode() == ::Mode::Hit) { + if (Inserted) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (!Inserted) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_TryEmplace" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct TryEmplaceHint : Base { + using Base::Base; + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto H = Data.Hints[I].begin(); + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.try_emplace(*H, K, 1)); +#else + auto Inserted = Map.try_emplace(*H, K, 1); + if (Mode() == ::Mode::Hit) { + if (Inserted != *H) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (++Inserted != *H) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + ++H; + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + template < ::Hint hint> + typename std::enable_if::type + run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + auto Third = *(Data.Hints[I].begin() + 2); + for (auto K : Data.Keys) { + auto Itor = hint == ::Hint::Begin + ? Map.begin() + : hint == ::Hint::Third ? Third : Map.end(); +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.try_emplace(Itor, K, 1)); +#else + size_t Size = Map.size(); + Map.try_emplace(Itor, K, 1); + if (Mode() == ::Mode::Hit) { + if (Size != Map.size()) + State.SkipWithError("Emplaced a duplicate element"); + } else { + if (Size + 1 != Map.size()) + State.SkipWithError("Failed to emplace a new element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + void run(benchmark::State& State) const { + static constexpr auto h = Hint(); + run(State); + } + + std::string name() const { + return "BM_TryEmplaceHint" + baseName() + Mode::name() + Hint::name(); + } +}; + +template +struct Erase : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.erase(K)); +#else + size_t I = Map.erase(K); + if (Mode() == ::Mode::Hit) { + if (I == 0) + State.SkipWithError("Did not find the existing element"); + } else { + if (I == 1) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_Erase" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct EraseIterator : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode::Hit, + Order::value == ::Order::Random ? Shuffle::Hints : Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (size_t I = 0; I < Data.Maps.size(); ++I) { + auto& Map = Data.Maps[I]; + for (auto H : Data.Hints[I]) { + benchmark::DoNotOptimize(Map.erase(H)); + } +#ifdef VALIDATE + if (!Map.empty()) + State.SkipWithError("Did not erase the entire map"); +#endif + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode::Hit, + Order::value == ::Order::Random ? Shuffle::Hints + : Shuffle::None, + 1000); + State.ResumeTiming(); + } + } + + std::string name() const { + return "BM_EraseIterator" + baseName() + Order::name(); + } +}; + +struct EraseRange : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + while (State.KeepRunningBatch(MapSize * Data.Maps.size())) { + for (auto& Map : Data.Maps) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.erase(Map.begin(), Map.end())); +#else + Map.erase(Map.begin(), Map.end()); + if (!Map.empty()) + State.SkipWithError("Did not erase the entire map"); +#endif + } + + State.PauseTiming(); + Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000); + State.ResumeTiming(); + } + } + + std::string name() const { return "BM_EraseRange" + baseName(); } +}; + +//*******************************************************************| +// Lookup | +//*******************************************************************| + +template +struct Count : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.count(K)); +#else + size_t I = Map.count(K); + if (Mode() == ::Mode::Hit) { + if (I == 0) + State.SkipWithError("Did not find the existing element"); + } else { + if (I == 1) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + } + + std::string name() const { + return "BM_Count" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct Find : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.find(K)); +#else + auto Itor = Map.find(K); + if (Mode() == ::Mode::Hit) { + if (Itor == Map.end()) + State.SkipWithError("Did not find the existing element"); + } else { + if (Itor != Map.end()) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + } + + std::string name() const { + return "BM_Find" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct EqualRange : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.equal_range(K)); +#else + auto Range = Map.equal_range(K); + if (Mode() == ::Mode::Hit) { + // Adjust validation for the last element. + auto Key = K; + if (Range.second == Map.end() && K == 2 * MapSize) { + --Range.second; + Key -= 2; + } + if (Range.first == Map.end() || Range.first->first != K || + Range.second == Map.end() || Range.second->first - 2 != Key) + State.SkipWithError("Did not find the existing element"); + } else { + if (Range.first == Map.end() || Range.first->first - 1 != K || + Range.second == Map.end() || Range.second->first - 1 != K) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + } + + std::string name() const { + return "BM_EqualRange" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct LowerBound : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.lower_bound(K)); +#else + auto Itor = Map.lower_bound(K); + if (Mode() == ::Mode::Hit) { + if (Itor == Map.end() || Itor->first != K) + State.SkipWithError("Did not find the existing element"); + } else { + if (Itor == Map.end() || Itor->first - 1 != K) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + } + + std::string name() const { + return "BM_LowerBound" + baseName() + Mode::name() + Order::name(); + } +}; + +template +struct UpperBound : Base { + using Base::Base; + + void run(benchmark::State& State) const { + auto Data = makeTestingSets( + MapSize, Mode(), + Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1); + auto& Map = Data.Maps.front(); + while (State.KeepRunningBatch(MapSize)) { + for (auto K : Data.Keys) { +#ifndef VALIDATE + benchmark::DoNotOptimize(Map.upper_bound(K)); +#else + std::map::iterator Itor = Map.upper_bound(K); + if (Mode() == ::Mode::Hit) { + // Adjust validation for the last element. + auto Key = K; + if (Itor == Map.end() && K == 2 * MapSize) { + --Itor; + Key -= 2; + } + if (Itor == Map.end() || Itor->first - 2 != Key) + State.SkipWithError("Did not find the existing element"); + } else { + if (Itor == Map.end() || Itor->first - 1 != K) + State.SkipWithError("Did find the non-existing element"); + } +#endif + } + } + } + + std::string name() const { + return "BM_UpperBound" + baseName() + Mode::name() + Order::name(); + } +}; + +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + +#ifdef VALIDATE + const std::vector MapSize{10}; +#else + const std::vector MapSize{10, 100, 1000, 10000, 100000, 1000000}; +#endif + + // Member functions + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + + // Capacity + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + + // Modifiers + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + + // Lookup + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + makeCartesianProductBenchmark(MapSize); + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/std_format_spec_string_unicode.bench.cpp b/benchmarks/std_format_spec_string_unicode.bench.cpp new file mode 100644 index 000000000..156eaebd4 --- /dev/null +++ b/benchmarks/std_format_spec_string_unicode.bench.cpp @@ -0,0 +1,196 @@ +// 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_HAS_NO_UNICODE + +#include +#include + +#include "benchmark/benchmark.h" + +#include "test_macros.h" + +template +class tester { + static constexpr size_t size_ = N - 1; + std::array data_; + +public: + explicit constexpr tester(const CharT (&input)[N]) { + auto it = data_.begin(); + for (int i = 0; i < 100; ++i) + it = std::copy_n(input, size_, it); + } + + constexpr size_t size() const noexcept { return data_.size(); } + constexpr const CharT* begin() const noexcept { return data_.begin(); } + constexpr const CharT* end() const noexcept { return data_.end(); } + + void test(benchmark::State& state) const { + for (auto _ : state) + benchmark::DoNotOptimize(std::__format_spec::__get_string_alignment( + begin(), end(), 1'000'000, 1'000'000)); + state.SetItemsProcessed(state.iterations() * size()); + } +}; + +#define TEST(u8) \ + if constexpr (std::same_as) { \ + constexpr auto p = tester{u8}; \ + p.test(state); \ + } else if constexpr (std::same_as) { \ + constexpr auto p = tester{TEST_CONCAT(u, u8)}; \ + p.test(state); \ + } else { \ + constexpr auto p = tester{TEST_CONCAT(U, u8)}; \ + p.test(state); \ + } + +template +static void BM_EstimateLengthNoMultiByte(benchmark::State& state) { + TEST("The quick brown fox jumps over the lazy dog"); +} + +template +static void BM_EstimateLengthTwoByteDE(benchmark::State& state) { + static_assert(sizeof("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich") == 67); + + // https://en.wikipedia.org/wiki/Pangram + TEST("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich"); +} + +template +static void BM_EstimateLengthTwoBytePL(benchmark::State& state) { + static_assert(sizeof("Stróż pchnął kość w quiz gędźb vel fax myjń") == 53); + + // https://en.wikipedia.org/wiki/Pangram + TEST("Stróż pchnął kość w quiz gędźb vel fax myjń"); +} + +// All values below are 1100, which is is the first multi column sequence. +template +static void BM_EstimateLengthThreeByteSingleColumnLow(benchmark::State& state) { + static_assert(sizeof("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807" + "\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f") == + 49); + + TEST("\u0800\u0801\u0802\u0803\u0804\u0805\u0806\u0807" + "\u0808\u0809\u080a\u080b\u080c\u080d\u080e\u080f"); +} + +template +static void +BM_EstimateLengthThreeByteSingleColumnHigh(benchmark::State& state) { + static_assert(sizeof("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807" + "\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f") == + 49); + + TEST("\u1800\u1801\u1802\u1803\u1804\u1805\u1806\u1807" + "\u1808\u1809\u180a\u180b\u180c\u180d\u180e\u180f"); +} + +template +static void BM_EstimateLengthThreeByteDoubleColumn(benchmark::State& state) { + static_assert(sizeof("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807" + "\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f") == + 49); + + TEST("\u1100\u0801\u0802\u0803\u0804\u0805\u0806\u0807" + "\u1108\u0809\u080a\u080b\u080c\u080d\u080e\u080f"); +} + +template +static void BM_EstimateLengthThreeByte(benchmark::State& state) { + static_assert(sizeof("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000" + "\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e") == + 49); + + TEST("\u1400\u1501\ubbbb\uff00\u0800\u4099\uabcd\u4000" + "\u8ead\ubeef\u1111\u4987\u4321\uffff\u357a\ud50e"); +} + +template +static void BM_EstimateLengthFourByteSingleColumn(benchmark::State& state) { + static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003" + "\U00010004\U00010005\U00010006\U00010007" + "\U00010008\U00010009\U0001000a\U0001000b" + "\U0001000c\U0001000d\U0001000e\U0001000f") == 65); + + TEST("\U00010000\U00010001\U00010002\U00010003" + "\U00010004\U00010005\U00010006\U00010007" + "\U00010008\U00010009\U0001000a\U0001000b" + "\U0001000c\U0001000d\U0001000e\U0001000f"); +} + +template +static void BM_EstimateLengthFourByteDoubleColumn(benchmark::State& state) { + static_assert(sizeof("\U00020000\U00020002\U00020002\U00020003" + "\U00020004\U00020005\U00020006\U00020007" + "\U00020008\U00020009\U0002000a\U0002000b" + "\U0002000c\U0002000d\U0002000e\U0002000f") == 65); + + TEST("\U00020000\U00020002\U00020002\U00020003" + "\U00020004\U00020005\U00020006\U00020007" + "\U00020008\U00020009\U0002000a\U0002000b" + "\U0002000c\U0002000d\U0002000e\U0002000f"); +} + +template +static void BM_EstimateLengthFourByte(benchmark::State& state) { + static_assert(sizeof("\U00010000\U00010001\U00010002\U00010003" + "\U00020004\U00020005\U00020006\U00020007" + "\U00010008\U00010009\U0001000a\U0001000b" + "\U0002000c\U0002000d\U0002000e\U0002000f") == 65); + + TEST("\U00010000\U00010001\U00010002\U00010003" + "\U00020004\U00020005\U00020006\U00020007" + "\U00010008\U00010009\U0001000a\U0001000b" + "\U0002000c\U0002000d\U0002000e\U0002000f"); +} + +BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char); + +BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char16_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char16_t); + +BENCHMARK_TEMPLATE(BM_EstimateLengthNoMultiByte, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoByteDE, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthTwoBytePL, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnLow, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteSingleColumnHigh, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByteDoubleColumn, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthThreeByte, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteSingleColumn, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByteDoubleColumn, char32_t); +BENCHMARK_TEMPLATE(BM_EstimateLengthFourByte, char32_t); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} +#else +int main(int, char**) { return 0; } +#endif diff --git a/benchmarks/string.bench.cpp b/benchmarks/string.bench.cpp index c4f209039..e43ad3212 100644 --- a/benchmarks/string.bench.cpp +++ b/benchmarks/string.bench.cpp @@ -124,6 +124,20 @@ TEST_ALWAYS_INLINE const char* getHugeString(DiffType D) { } } +TEST_ALWAYS_INLINE const char* getString(Length L, + DiffType D = DiffType::Control) { + switch (L) { + case Length::Empty: + return ""; + case Length::Small: + return getSmallString(D); + case Length::Large: + return getLargeString(D); + case Length::Huge: + return getHugeString(D); + } +} + TEST_ALWAYS_INLINE std::string makeString(Length L, DiffType D = DiffType::Control, Opacity O = Opacity::Transparent) { @@ -220,6 +234,164 @@ struct StringMove { static std::string name() { return "BM_StringMove" + Length::name(); } }; +template +struct StringResizeDefaultInit { + static void run(benchmark::State& state) { + constexpr bool opaque = Opaque{} == Opacity::Opaque; + constexpr int kNumStrings = 4 << 10; + size_t length = makeString(Length()).size(); + std::string strings[kNumStrings]; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + std::string().swap(strings[i]); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i].__resize_default_init(maybeOpaque(length, opaque)); + } + } + } + + static std::string name() { + return "BM_StringResizeDefaultInit" + Length::name() + Opaque::name(); + } +}; + +template +struct StringAssignStr { + static void run(benchmark::State& state) { + constexpr bool opaque = Opaque{} == Opacity::Opaque; + constexpr int kNumStrings = 4 << 10; + std::string src = makeString(Length()); + std::string strings[kNumStrings]; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + std::string().swap(strings[i]); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i] = *maybeOpaque(&src, opaque); + } + } + } + + static std::string name() { + return "BM_StringAssignStr" + Length::name() + Opaque::name(); + } +}; + +template +struct StringAssignAsciiz { + static void run(benchmark::State& state) { + constexpr bool opaque = Opaque{} == Opacity::Opaque; + constexpr int kNumStrings = 4 << 10; + std::string strings[kNumStrings]; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + std::string().swap(strings[i]); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i] = maybeOpaque(getString(Length()), opaque); + } + } + } + + static std::string name() { + return "BM_StringAssignAsciiz" + Length::name() + Opaque::name(); + } +}; + +template +struct StringEraseToEnd { + static void run(benchmark::State& state) { + constexpr bool opaque = Opaque{} == Opacity::Opaque; + constexpr int kNumStrings = 4 << 10; + std::string strings[kNumStrings]; + const int mid = makeString(Length()).size() / 2; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i] = makeString(Length()); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i].erase(maybeOpaque(mid, opaque), + maybeOpaque(std::string::npos, opaque)); + } + } + } + + static std::string name() { + return "BM_StringEraseToEnd" + Length::name() + Opaque::name(); + } +}; + +template +struct StringEraseWithMove { + static void run(benchmark::State& state) { + constexpr bool opaque = Opaque{} == Opacity::Opaque; + constexpr int kNumStrings = 4 << 10; + std::string strings[kNumStrings]; + const int n = makeString(Length()).size() / 2; + const int pos = n / 2; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i] = makeString(Length()); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings; ++i) { + strings[i].erase(maybeOpaque(pos, opaque), maybeOpaque(n, opaque)); + } + } + } + + static std::string name() { + return "BM_StringEraseWithMove" + Length::name() + Opaque::name(); + } +}; + +template +struct StringAssignAsciizMix { + static void run(benchmark::State& state) { + constexpr auto O = Opaque{}; + constexpr auto D = DiffType::Control; + constexpr int kNumStrings = 4 << 10; + std::string strings[kNumStrings]; + while (state.KeepRunningBatch(kNumStrings)) { + state.PauseTiming(); + for (int i = 0; i < kNumStrings; ++i) { + std::string().swap(strings[i]); + } + benchmark::DoNotOptimize(strings); + state.ResumeTiming(); + for (int i = 0; i < kNumStrings - 7; i += 8) { + strings[i + 0] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + strings[i + 1] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + strings[i + 2] = maybeOpaque(getLargeString(D), O == Opacity::Opaque); + strings[i + 3] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + strings[i + 4] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + strings[i + 5] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + strings[i + 6] = maybeOpaque(getLargeString(D), O == Opacity::Opaque); + strings[i + 7] = maybeOpaque(getSmallString(D), O == Opacity::Opaque); + } + } + } + + static std::string name() { + return "BM_StringAssignAsciizMix" + Opaque::name(); + } +}; + enum class Relation { Eq, Less, Compare }; struct AllRelations : EnumValuesAsTuple { static constexpr const char* Names[] = {"Eq", "Less", "Compare"}; @@ -426,9 +598,18 @@ int main(int argc, char** argv) { makeCartesianProductBenchmark(); + + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); makeCartesianProductBenchmark(); makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); + makeCartesianProductBenchmark(); makeCartesianProductBenchmark(); makeCartesianProductBenchmark +#include +#include + +#include "benchmark/benchmark.h" +#include "test_macros.h" + +static const std::array input = [] { + std::mt19937 generator; + std::uniform_int_distribution distribution(0, std::numeric_limits::max()); + std::array result; + std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); }); + return result; +}(); + +static void BM_to_chars_good(benchmark::State& state) { + char buffer[128]; + int base = state.range(0); + while (state.KeepRunningBatch(input.size())) + for (auto value : input) + benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[128], value, base)); +} +BENCHMARK(BM_to_chars_good)->DenseRange(2, 36, 1); + +static void BM_to_chars_bad(benchmark::State& state) { + char buffer[128]; + int base = state.range(0); + struct sample { + unsigned size; + unsigned value; + }; + std::array data; + // Assume the failure occurs, on average, halfway during the conversion. + std::transform(input.begin(), input.end(), data.begin(), [&](unsigned value) { + std::to_chars_result result = std::to_chars(buffer, &buffer[128], value, base); + return sample{unsigned((result.ptr - buffer) / 2), value}; + }); + + while (state.KeepRunningBatch(data.size())) + for (auto element : data) + benchmark::DoNotOptimize(std::to_chars(buffer, &buffer[element.size], element.value, base)); +} +BENCHMARK(BM_to_chars_bad)->DenseRange(2, 36, 1); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/benchmarks/unordered_set_operations.bench.cpp b/benchmarks/unordered_set_operations.bench.cpp index 3824386e7..e0030d6c4 100644 --- a/benchmarks/unordered_set_operations.bench.cpp +++ b/benchmarks/unordered_set_operations.bench.cpp @@ -148,7 +148,7 @@ BENCHMARK_CAPTURE(BM_Hash, // ---------------------------------------------------------------------------// -// Sorted Assending // +// Sorted Ascending // BENCHMARK_CAPTURE(BM_InsertValue, unordered_set_uint32, std::unordered_set{}, @@ -159,7 +159,7 @@ BENCHMARK_CAPTURE(BM_InsertValue, std::unordered_set{}, getSortedIntegerInputs)->Arg(TestNumInputs); -// Top Bytes // +// Top Bytes // BENCHMARK_CAPTURE(BM_InsertValue, unordered_set_top_bits_uint32, std::unordered_set{}, diff --git a/benchmarks/variant_visit_1.bench.cpp b/benchmarks/variant_visit_1.bench.cpp new file mode 100644 index 000000000..7d736f8ab --- /dev/null +++ b/benchmarks/variant_visit_1.bench.cpp @@ -0,0 +1,27 @@ +#include "benchmark/benchmark.h" + +#include "VariantBenchmarks.h" + +using namespace VariantBenchmarks; + +BENCHMARK_TEMPLATE(BM_Visit, 1, 1); +BENCHMARK_TEMPLATE(BM_Visit, 1, 2); +BENCHMARK_TEMPLATE(BM_Visit, 1, 3); +BENCHMARK_TEMPLATE(BM_Visit, 1, 4); +BENCHMARK_TEMPLATE(BM_Visit, 1, 5); +BENCHMARK_TEMPLATE(BM_Visit, 1, 6); +BENCHMARK_TEMPLATE(BM_Visit, 1, 7); +BENCHMARK_TEMPLATE(BM_Visit, 1, 8); +BENCHMARK_TEMPLATE(BM_Visit, 1, 9); +BENCHMARK_TEMPLATE(BM_Visit, 1, 10); +BENCHMARK_TEMPLATE(BM_Visit, 1, 20); +BENCHMARK_TEMPLATE(BM_Visit, 1, 30); +BENCHMARK_TEMPLATE(BM_Visit, 1, 40); +BENCHMARK_TEMPLATE(BM_Visit, 1, 50); +BENCHMARK_TEMPLATE(BM_Visit, 1, 60); +BENCHMARK_TEMPLATE(BM_Visit, 1, 70); +BENCHMARK_TEMPLATE(BM_Visit, 1, 80); +BENCHMARK_TEMPLATE(BM_Visit, 1, 90); +BENCHMARK_TEMPLATE(BM_Visit, 1, 100); + +BENCHMARK_MAIN(); diff --git a/benchmarks/variant_visit_2.bench.cpp b/benchmarks/variant_visit_2.bench.cpp new file mode 100644 index 000000000..ed26cd44c --- /dev/null +++ b/benchmarks/variant_visit_2.bench.cpp @@ -0,0 +1,22 @@ +#include "benchmark/benchmark.h" + +#include "VariantBenchmarks.h" + +using namespace VariantBenchmarks; + +BENCHMARK_TEMPLATE(BM_Visit, 2, 1); +BENCHMARK_TEMPLATE(BM_Visit, 2, 2); +BENCHMARK_TEMPLATE(BM_Visit, 2, 3); +BENCHMARK_TEMPLATE(BM_Visit, 2, 4); +BENCHMARK_TEMPLATE(BM_Visit, 2, 5); +BENCHMARK_TEMPLATE(BM_Visit, 2, 6); +BENCHMARK_TEMPLATE(BM_Visit, 2, 7); +BENCHMARK_TEMPLATE(BM_Visit, 2, 8); +BENCHMARK_TEMPLATE(BM_Visit, 2, 9); +BENCHMARK_TEMPLATE(BM_Visit, 2, 10); +BENCHMARK_TEMPLATE(BM_Visit, 2, 20); +BENCHMARK_TEMPLATE(BM_Visit, 2, 30); +BENCHMARK_TEMPLATE(BM_Visit, 2, 40); +BENCHMARK_TEMPLATE(BM_Visit, 2, 50); + +BENCHMARK_MAIN(); diff --git a/benchmarks/variant_visit_3.bench.cpp b/benchmarks/variant_visit_3.bench.cpp new file mode 100644 index 000000000..b20d50391 --- /dev/null +++ b/benchmarks/variant_visit_3.bench.cpp @@ -0,0 +1,20 @@ +#include "benchmark/benchmark.h" + +#include "VariantBenchmarks.h" + +using namespace VariantBenchmarks; + +BENCHMARK_TEMPLATE(BM_Visit, 3, 1); +BENCHMARK_TEMPLATE(BM_Visit, 3, 2); +BENCHMARK_TEMPLATE(BM_Visit, 3, 3); +BENCHMARK_TEMPLATE(BM_Visit, 3, 4); +BENCHMARK_TEMPLATE(BM_Visit, 3, 5); +BENCHMARK_TEMPLATE(BM_Visit, 3, 6); +BENCHMARK_TEMPLATE(BM_Visit, 3, 7); +BENCHMARK_TEMPLATE(BM_Visit, 3, 8); +BENCHMARK_TEMPLATE(BM_Visit, 3, 9); +BENCHMARK_TEMPLATE(BM_Visit, 3, 10); +BENCHMARK_TEMPLATE(BM_Visit, 3, 15); +BENCHMARK_TEMPLATE(BM_Visit, 3, 20); + +BENCHMARK_MAIN(); diff --git a/cmake/Modules/CheckLibcxxAtomic.cmake b/cmake/Modules/CheckLibcxxAtomic.cmake deleted file mode 100644 index 7fe5a6278..000000000 --- a/cmake/Modules/CheckLibcxxAtomic.cmake +++ /dev/null @@ -1,56 +0,0 @@ -INCLUDE(CheckCXXSourceCompiles) - -# Sometimes linking against libatomic is required for atomic ops, if -# the platform doesn't support lock-free atomics. -# -# We could modify LLVM's CheckAtomic module and have it check for 64-bit -# atomics instead. However, we would like to avoid careless uses of 64-bit -# atomics inside LLVM over time on 32-bit platforms. - -function(check_cxx_atomics varname) - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs -std=c++11 -nostdinc++ -isystem ${LIBCXX_SOURCE_DIR}/include") - if (${LIBCXX_GCC_TOOLCHAIN}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}") - endif() - if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") - endif() - if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters") - endif() - check_cxx_source_compiles(" -#include -#include -std::atomic x; -std::atomic y; -int main(int, char**) { - return x + y; -} -" ${varname}) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) -endfunction(check_cxx_atomics) - -# Perform the check for 64bit atomics without libatomic. It may have been -# added to the required libraries during in the configuration of LLVM, which -# would cause the check for CXX atomics without libatomic to incorrectly pass. -if (CMAKE_REQUIRED_LIBRARIES) - set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) - list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "atomic") - check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB) - set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES}) -endif() - -check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB) -# If not, check if the library exists, and atomics work with it. -if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB) - if(LIBCXX_HAS_ATOMIC_LIB) - list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") - check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) - if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) - message(WARNING "Host compiler must support std::atomic!") - endif() - else() - message(WARNING "Host compiler appears to require libatomic, but cannot find it.") - endif() -endif() diff --git a/cmake/Modules/DefineLinkerScript.cmake b/cmake/Modules/DefineLinkerScript.cmake index 2e68121f6..71a430867 100644 --- a/cmake/Modules/DefineLinkerScript.cmake +++ b/cmake/Modules/DefineLinkerScript.cmake @@ -31,13 +31,17 @@ function(define_linker_script target) set(link_libraries) if (interface_libs) foreach(lib IN LISTS interface_libs) - if (TARGET "${lib}" OR - (${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR - (${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND)) - list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$") - else() - list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${lib}") + if ("${lib}" MATCHES "cxx-headers|ParallelSTL") + continue() endif() + # If ${lib} is not a target, we use a dummy target which we know will + # have an OUTPUT_NAME property so that CMake doesn't fail when evaluating + # the non-selected branch of the `IF`. It doesn't matter what it evaluates + # to because it's not selected, but it must not cause an error. + # See https://gitlab.kitware.com/cmake/cmake/-/issues/21045. + set(output_name_tgt "$,${lib},${target}>") + set(libname "$,$,${lib}>") + list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${libname}") endforeach() endif() string(REPLACE ";" " " link_libraries "${link_libraries}") diff --git a/cmake/Modules/HandleCompilerRT.cmake b/cmake/Modules/HandleCompilerRT.cmake deleted file mode 100644 index 1ce256574..000000000 --- a/cmake/Modules/HandleCompilerRT.cmake +++ /dev/null @@ -1,64 +0,0 @@ -function(find_compiler_rt_library name dest) - if (NOT DEFINED LIBCXX_COMPILE_FLAGS) - message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function") - endif() - set(dest "" PARENT_SCOPE) - set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS} - "--rtlib=compiler-rt" "--print-libgcc-file-name") - if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) - list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") - endif() - get_property(LIBCXX_CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) - string(REPLACE " " ";" LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}") - list(APPEND CLANG_COMMAND ${LIBCXX_CXX_FLAGS}) - execute_process( - COMMAND ${CLANG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE LIBRARY_FILE - ) - string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) - file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE) - string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}") - if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}") - message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}") - set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE) - else() - message(STATUS "Failed to find compiler-rt library") - endif() -endfunction() - -function(find_compiler_rt_dir dest) - if (NOT DEFINED LIBCXX_COMPILE_FLAGS) - message(FATAL_ERROR "LIBCXX_COMPILE_FLAGS must be defined when using this function") - endif() - set(dest "" PARENT_SCOPE) - if (APPLE) - set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS} - "-print-file-name=lib") - execute_process( - COMMAND ${CLANG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE LIBRARY_DIR - ) - string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR) - file(TO_CMAKE_PATH "${LIBRARY_DIR}" LIBRARY_DIR) - set(LIBRARY_DIR "${LIBRARY_DIR}/darwin") - else() - set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS} - "--rtlib=compiler-rt" "--print-libgcc-file-name") - execute_process( - COMMAND ${CLANG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE LIBRARY_FILE - ) - string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) - file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE) - get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY) - endif() - if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}") - message(STATUS "Found compiler-rt directory: ${LIBRARY_DIR}") - set(${dest} "${LIBRARY_DIR}" PARENT_SCOPE) - else() - message(STATUS "Failed to find compiler-rt directory") - endif() -endfunction() diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake index 10f100f7f..9b5df6e01 100644 --- a/cmake/Modules/HandleLibCXXABI.cmake +++ b/cmake/Modules/HandleLibCXXABI.cmake @@ -1,8 +1,9 @@ - #=============================================================================== # Add an ABI library if appropriate #=============================================================================== +include(GNUInstallDirs) + # # _setup_abi: Set up the build to use an ABI library # @@ -37,8 +38,10 @@ macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs) foreach(fpath ${LIBCXX_ABILIB_FILES}) set(found FALSE) foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS}) + message(STATUS "Looking for ${fpath} in ${incpath}") if (EXISTS "${incpath}/${fpath}") set(found TRUE) + message(STATUS "Looking for ${fpath} in ${incpath} - found") get_filename_component(dstdir ${fpath} PATH) get_filename_component(ifile ${fpath} NAME) set(src ${incpath}/${fpath}) @@ -50,26 +53,28 @@ macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs) COMMENT "Copying C++ ABI header ${fpath}...") list(APPEND abilib_headers "${dst}") - if (NOT LIBCXX_USING_INSTALLED_LLVM AND LIBCXX_HEADER_DIR) - set(dst "${LIBCXX_HEADER_DIR}/include/c++/v1/${dstdir}/${fpath}") - add_custom_command(OUTPUT ${dst} - DEPENDS ${src} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying C++ ABI header ${fpath}...") - list(APPEND abilib_headers "${dst}") - endif() + # TODO: libc++ shouldn't be responsible for copying the libc++abi + # headers into the right location. + set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${dstdir}/${fpath}") + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying C++ ABI header ${fpath}...") + list(APPEND abilib_headers "${dst}") if (LIBCXX_INSTALL_HEADERS) install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}" - DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dstdir} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1/${dstdir}" COMPONENT cxx-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endif() + else() + message(STATUS "Looking for ${fpath} in ${incpath} - not found") endif() endforeach() if (NOT found) - message(WARNING "Failed to find ${fpath}") + message(WARNING "Failed to find ${fpath} in ${LIBCXX_CXX_ABI_INCLUDE_PATHS}") endif() endforeach() @@ -98,34 +103,41 @@ if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits" ) elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi") - if (LIBCXX_CXX_ABI_INTREE) - # Link against just-built "cxxabi" target. - set(CXXABI_SHARED_LIBNAME cxxabi_shared) - set(CXXABI_STATIC_LIBNAME cxxabi_static) - else() - # Assume c++abi is installed in the system, rely on -lc++abi link flag. - set(CXXABI_SHARED_LIBNAME "c++abi") - set(CXXABI_STATIC_LIBNAME "c++abi") + if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS) + set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_SOURCE_DIR}/../libcxxabi/include") endif() - if (LIBCXX_CXX_ABI_SYSTEM) - set(HEADERS "") + + if(LIBCXX_STANDALONE_BUILD AND NOT (LIBCXX_CXX_ABI_INTREE OR HAVE_LIBCXXABI)) + set(shared c++abi) + set(static c++abi) else() - set(HEADERS "cxxabi.h;__cxxabi_config.h") + set(shared cxxabi_shared) + set(static cxxabi_static) endif() + setup_abi_lib( "-DLIBCXX_BUILDING_LIBCXXABI" - "${CXXABI_SHARED_LIBNAME}" "${CXXABI_STATIC_LIBNAME}" "${HEADERS}" "") + "${shared}" "${static}" "cxxabi.h;__cxxabi_config.h" "") +elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "system-libcxxabi") + setup_abi_lib( + "-DLIBCXX_BUILDING_LIBCXXABI" + "c++abi" "c++abi" "cxxabi.h;__cxxabi_config.h" "") elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt") + if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS) + set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1") + endif() + # libcxxrt does not provide aligned new and delete operators + set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON) setup_abi_lib( "-DLIBCXXRT" "cxxrt" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" "" ) elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime") - # Nothing TODO + # Nothing to do elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none") list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY") elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default") - # Nothing TODO + # Nothing to do else() message(FATAL_ERROR "Unsupported c++ abi: '${LIBCXX_CXX_ABI_LIBNAME}'. \ diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake index b0fb98b98..859cfc4a5 100644 --- a/cmake/Modules/HandleLibcxxFlags.cmake +++ b/cmake/Modules/HandleLibcxxFlags.cmake @@ -88,20 +88,17 @@ endmacro() macro(config_define_if condition def) if (${condition}) set(${def} ON) - set(LIBCXX_NEEDS_SITE_CONFIG ON) endif() endmacro() macro(config_define_if_not condition def) if (NOT ${condition}) set(${def} ON) - set(LIBCXX_NEEDS_SITE_CONFIG ON) endif() endmacro() macro(config_define value def) set(${def} ${value}) - set(LIBCXX_NEEDS_SITE_CONFIG ON) endmacro() # Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', @@ -124,6 +121,17 @@ macro(add_target_flags_if condition) endif() endmacro() +# Add all the flags supported by the compiler to all of +# 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS' +# and 'LIBCXX_LINK_FLAGS'. +macro(add_target_flags_if_supported) + foreach(flag ${ARGN}) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") + add_target_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag}) + endforeach() +endmacro() + # Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and # 'LIBCXX_LINK_FLAGS'. macro(add_flags) diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake deleted file mode 100644 index 5746afb5e..000000000 --- a/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ /dev/null @@ -1,142 +0,0 @@ -macro(find_llvm_parts) -# Rely on llvm-config. - set(CONFIG_OUTPUT) - if(NOT LLVM_CONFIG_PATH) - find_program(LLVM_CONFIG_PATH "llvm-config") - endif() - if(DEFINED LLVM_PATH) - set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include") - set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree") - set(LLVM_MAIN_SRC_DIR ${LLVM_PATH}) - set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules") - if (NOT IS_DIRECTORY "${LLVM_PATH}") - message(FATAL_ERROR "The provided LLVM_PATH (${LLVM_PATH}) is not a valid directory") - endif() - elseif(LLVM_CONFIG_PATH) - message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") - set(LIBCXX_USING_INSTALLED_LLVM 1) - set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} - "--includedir" - "--prefix" - "--src-root") - execute_process( - COMMAND ${CONFIG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE CONFIG_OUTPUT - ) - if(NOT HAD_ERROR) - string(REGEX REPLACE - "[ \t]*[\r\n]+[ \t]*" ";" - CONFIG_OUTPUT ${CONFIG_OUTPUT}) - else() - string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") - message(STATUS "${CONFIG_COMMAND_STR}") - message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") - endif() - - list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) - list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) - list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) - - set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") - set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") - set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") - - # --cmakedir is supported since llvm r291218 (4.0 release) - execute_process( - COMMAND ${LLVM_CONFIG_PATH} --cmakedir - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE CONFIG_OUTPUT - ERROR_QUIET) - if(NOT HAD_ERROR) - string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH_FROM_LLVM_CONFIG) - file(TO_CMAKE_PATH "${LLVM_CMAKE_PATH_FROM_LLVM_CONFIG}" LLVM_CMAKE_PATH) - else() - file(TO_CMAKE_PATH "${LLVM_BINARY_DIR}" LLVM_BINARY_DIR_CMAKE_STYLE) - set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") - endif() - else() - set(LLVM_FOUND OFF) - message(WARNING "UNSUPPORTED LIBCXX CONFIGURATION DETECTED: " - "llvm-config not found and LLVM_PATH not defined.\n" - "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config " - "or -DLLVM_PATH=path/to/llvm-source-root.") - return() - endif() - - if (EXISTS "${LLVM_CMAKE_PATH}") - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") - elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules") - list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") - else() - set(LLVM_FOUND OFF) - message(WARNING "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found") - return() - endif() - - set(LLVM_FOUND ON) -endmacro(find_llvm_parts) - -macro(configure_out_of_tree_llvm) - message(STATUS "Configuring for standalone build.") - set(LIBCXX_STANDALONE_BUILD 1) - - find_llvm_parts() - - # Add LLVM Functions -------------------------------------------------------- - if (LLVM_FOUND AND LIBCXX_USING_INSTALLED_LLVM) - include(LLVMConfig) # For TARGET_TRIPLE - else() - if (WIN32) - set(LLVM_ON_UNIX 0) - set(LLVM_ON_WIN32 1) - else() - set(LLVM_ON_UNIX 1) - set(LLVM_ON_WIN32 0) - endif() - endif() - if (LLVM_FOUND) - include(AddLLVM OPTIONAL) - endif() - - # LLVM Options -------------------------------------------------------------- - if (NOT DEFINED LLVM_INCLUDE_TESTS) - set(LLVM_INCLUDE_TESTS ${LLVM_FOUND}) - endif() - if (NOT DEFINED LLVM_INCLUDE_DOCS) - set(LLVM_INCLUDE_DOCS ${LLVM_FOUND}) - endif() - if (NOT DEFINED LLVM_ENABLE_SPHINX) - set(LLVM_ENABLE_SPHINX OFF) - endif() - - # In a standalone build, we don't have llvm to automatically generate the - # llvm-lit script for us. So we need to provide an explicit directory that - # the configurator should write the script into. - set(LLVM_LIT_OUTPUT_DIR "${libcxx_BINARY_DIR}/bin") - - if (LLVM_INCLUDE_TESTS) - # Required LIT Configuration ------------------------------------------------ - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") - set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - endif() - - # Required doc configuration - if (LLVM_ENABLE_SPHINX) - find_package(Sphinx REQUIRED) - endif() - - if (LLVM_ON_UNIX AND NOT APPLE) - set(LLVM_HAVE_LINK_VERSION_SCRIPT 1) - else() - set(LLVM_HAVE_LINK_VERSION_SCRIPT 0) - endif() -endmacro(configure_out_of_tree_llvm) - -configure_out_of_tree_llvm() diff --git a/cmake/caches/AArch64.cmake b/cmake/caches/AArch64.cmake new file mode 100644 index 000000000..33356a7ee --- /dev/null +++ b/cmake/caches/AArch64.cmake @@ -0,0 +1,2 @@ +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXX_TARGET_TRIPLE "aarch64-linux-gnu" CACHE STRING "") diff --git a/cmake/caches/AIX.cmake b/cmake/caches/AIX.cmake new file mode 100644 index 000000000..029b8deae --- /dev/null +++ b/cmake/caches/AIX.cmake @@ -0,0 +1,16 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") +set(CMAKE_C_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "") +set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-G -Wl,-bcdtors:all:-2147483548:s" CACHE STRING "") + +set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "") +set(LIBCXX_ABI_VERSION "1" CACHE STRING "") +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") diff --git a/cmake/caches/Apple.cmake b/cmake/caches/Apple.cmake index af4ea2c4c..6f4030ec0 100644 --- a/cmake/caches/Apple.cmake +++ b/cmake/caches/Apple.cmake @@ -2,14 +2,22 @@ set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "") set(CMAKE_POSITION_INDEPENDENT_CODE OFF CACHE BOOL "") set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") -set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "") - +set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "") set(LIBCXX_ABI_VERSION "1" CACHE STRING "") - set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") -set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") - -set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "") -set(LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") - +set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") set(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT ON CACHE BOOL "") +set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "") +set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "") + +set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") +set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST ON CACHE BOOL "") + +set(LIBCXX_TEST_PARAMS "stdlib=apple-libc++" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Armv7Arm.cmake b/cmake/caches/Armv7Arm.cmake new file mode 100644 index 000000000..0e9dc10e9 --- /dev/null +++ b/cmake/caches/Armv7Arm.cmake @@ -0,0 +1,4 @@ +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXX_TARGET_TRIPLE "armv7l-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "") +set(CMAKE_C_FLAGS "-marm" CACHE STRING "") diff --git a/cmake/caches/Armv7Thumb-noexceptions.cmake b/cmake/caches/Armv7Thumb-noexceptions.cmake new file mode 100644 index 000000000..61cd3bf73 --- /dev/null +++ b/cmake/caches/Armv7Thumb-noexceptions.cmake @@ -0,0 +1,6 @@ +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXX_TARGET_TRIPLE "armv7l-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "") +set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "") +set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/cmake/caches/Armv8Arm.cmake b/cmake/caches/Armv8Arm.cmake new file mode 100644 index 000000000..eee2eb46d --- /dev/null +++ b/cmake/caches/Armv8Arm.cmake @@ -0,0 +1,4 @@ +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXX_TARGET_TRIPLE "armv8l-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "") +set(CMAKE_C_FLAGS "-marm" CACHE STRING "") diff --git a/cmake/caches/Armv8Thumb-noexceptions.cmake b/cmake/caches/Armv8Thumb-noexceptions.cmake new file mode 100644 index 000000000..9c2f90661 --- /dev/null +++ b/cmake/caches/Armv8Thumb-noexceptions.cmake @@ -0,0 +1,6 @@ +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXX_TARGET_TRIPLE "armv8l-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "") +set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "") +set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/cmake/caches/FreeBSD.cmake b/cmake/caches/FreeBSD.cmake new file mode 100644 index 000000000..9e66e3798 --- /dev/null +++ b/cmake/caches/FreeBSD.cmake @@ -0,0 +1,9 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "") + +set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "") +set(LIBCXX_ABI_VERSION "1" CACHE STRING "") +set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_CXX_ABI libcxxrt CACHE STRING "") +set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") diff --git a/cmake/caches/Generic-asan.cmake b/cmake/caches/Generic-asan.cmake new file mode 100644 index 000000000..a86b34748 --- /dev/null +++ b/cmake/caches/Generic-asan.cmake @@ -0,0 +1,3 @@ +set(LLVM_USE_SANITIZER "Address" CACHE STRING "") +# This is a temporary (hopefully) workaround for an ASan issue (see https://llvm.org/D119410). +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -asan-use-private-alias=1" CACHE INTERNAL "") diff --git a/cmake/caches/Generic-assertions.cmake b/cmake/caches/Generic-assertions.cmake new file mode 100644 index 000000000..e8ef72ad1 --- /dev/null +++ b/cmake/caches/Generic-assertions.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "") diff --git a/cmake/caches/Generic-cxx03.cmake b/cmake/caches/Generic-cxx03.cmake new file mode 100644 index 000000000..5edb1c4cd --- /dev/null +++ b/cmake/caches/Generic-cxx03.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++03" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx11.cmake b/cmake/caches/Generic-cxx11.cmake new file mode 100644 index 000000000..f0f89c44d --- /dev/null +++ b/cmake/caches/Generic-cxx11.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++11" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx14.cmake b/cmake/caches/Generic-cxx14.cmake new file mode 100644 index 000000000..29c688d92 --- /dev/null +++ b/cmake/caches/Generic-cxx14.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++14" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx17.cmake b/cmake/caches/Generic-cxx17.cmake new file mode 100644 index 000000000..35bac9207 --- /dev/null +++ b/cmake/caches/Generic-cxx17.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++17" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx20.cmake b/cmake/caches/Generic-cxx20.cmake new file mode 100644 index 000000000..3c44fdaf0 --- /dev/null +++ b/cmake/caches/Generic-cxx20.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++20" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx2b.cmake b/cmake/caches/Generic-cxx2b.cmake new file mode 100644 index 000000000..be767dd2a --- /dev/null +++ b/cmake/caches/Generic-cxx2b.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "std=c++2b" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-debug-iterators.cmake b/cmake/caches/Generic-debug-iterators.cmake new file mode 100644 index 000000000..a43f27c02 --- /dev/null +++ b/cmake/caches/Generic-debug-iterators.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "debug_level=1" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-modules.cmake b/cmake/caches/Generic-modules.cmake new file mode 100644 index 000000000..29b4d4be1 --- /dev/null +++ b/cmake/caches/Generic-modules.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "enable_modules=True" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-msan.cmake b/cmake/caches/Generic-msan.cmake new file mode 100644 index 000000000..7c948f516 --- /dev/null +++ b/cmake/caches/Generic-msan.cmake @@ -0,0 +1 @@ +set(LLVM_USE_SANITIZER "MemoryWithOrigins" CACHE STRING "") diff --git a/cmake/caches/Generic-no-debug.cmake b/cmake/caches/Generic-no-debug.cmake new file mode 100644 index 000000000..a62760fa7 --- /dev/null +++ b/cmake/caches/Generic-no-debug.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-experimental.cmake b/cmake/caches/Generic-no-experimental.cmake new file mode 100644 index 000000000..0f055f4a9 --- /dev/null +++ b/cmake/caches/Generic-no-experimental.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") +set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-filesystem.cmake b/cmake/caches/Generic-no-filesystem.cmake new file mode 100644 index 000000000..4000f3a3e --- /dev/null +++ b/cmake/caches/Generic-no-filesystem.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-localization.cmake b/cmake/caches/Generic-no-localization.cmake new file mode 100644 index 000000000..79d6b44c7 --- /dev/null +++ b/cmake/caches/Generic-no-localization.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-random_device.cmake b/cmake/caches/Generic-no-random_device.cmake new file mode 100644 index 000000000..e9b4cc60c --- /dev/null +++ b/cmake/caches/Generic-no-random_device.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-unicode.cmake b/cmake/caches/Generic-no-unicode.cmake new file mode 100644 index 000000000..01160bf21 --- /dev/null +++ b/cmake/caches/Generic-no-unicode.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-wide-characters.cmake b/cmake/caches/Generic-no-wide-characters.cmake new file mode 100644 index 000000000..728d41086 --- /dev/null +++ b/cmake/caches/Generic-no-wide-characters.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-noexceptions.cmake b/cmake/caches/Generic-noexceptions.cmake new file mode 100644 index 000000000..f0dffef60 --- /dev/null +++ b/cmake/caches/Generic-noexceptions.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-singlethreaded.cmake b/cmake/caches/Generic-singlethreaded.cmake new file mode 100644 index 000000000..616baef1b --- /dev/null +++ b/cmake/caches/Generic-singlethreaded.cmake @@ -0,0 +1,3 @@ +set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "") +set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-static.cmake b/cmake/caches/Generic-static.cmake new file mode 100644 index 000000000..ed2bf8571 --- /dev/null +++ b/cmake/caches/Generic-static.cmake @@ -0,0 +1,3 @@ +set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-tsan.cmake b/cmake/caches/Generic-tsan.cmake new file mode 100644 index 000000000..a4b599e3e --- /dev/null +++ b/cmake/caches/Generic-tsan.cmake @@ -0,0 +1 @@ +set(LLVM_USE_SANITIZER "Thread" CACHE STRING "") diff --git a/cmake/caches/Generic-ubsan.cmake b/cmake/caches/Generic-ubsan.cmake new file mode 100644 index 000000000..7ad891e4a --- /dev/null +++ b/cmake/caches/Generic-ubsan.cmake @@ -0,0 +1,2 @@ +set(LLVM_USE_SANITIZER "Undefined" CACHE STRING "") +set(LIBCXX_ABI_UNSTABLE ON CACHE BOOL "") diff --git a/cmake/caches/MinGW.cmake b/cmake/caches/MinGW.cmake new file mode 100644 index 000000000..b9ac28006 --- /dev/null +++ b/cmake/caches/MinGW.cmake @@ -0,0 +1,18 @@ +set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") +set(LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "") + +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + +set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + +set(LIBCXX_TARGET_INFO "libcxx.test.target_info.MingwLocalTI" CACHE STRING "") + +# Without this flag, 'long double' (which is 80 bit on x86 mingw, but +# 64 bit in MSVC) isn't handled correctly in printf. +set(LIBCXX_EXTRA_SITE_DEFINES "__USE_MINGW_ANSI_STDIO=1" CACHE STRING "") diff --git a/cmake/caches/README.md b/cmake/caches/README.md new file mode 100644 index 000000000..60837ee29 --- /dev/null +++ b/cmake/caches/README.md @@ -0,0 +1,13 @@ +# libc++ / libc++abi configuration caches + +This directory contains CMake caches for the supported configurations of libc++. +Some of the configurations are specific to a vendor, others are generic and not +tied to any vendor. + +While we won't explicitly work to break configurations not listed here, any +configuration not listed here is not explicitly supported. If you use or ship +libc++ under a configuration not listed here, you should work with the libc++ +maintainers to make it into a supported configuration and add it here. + +Similarly, adding any new configuration that's not already covered must be +discussed with the libc++ maintainers as it entails a maintenance burden. diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index a7a684c9d..868bb89d8 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -1,9 +1,22 @@ include(CMakePushCheckState) include(CheckLibraryExists) +include(LLVMCheckCompilerLinkerFlag) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CheckCSourceCompiles) +# The compiler driver may be implicitly trying to link against libunwind. +# This is normally ok (libcxx relies on an unwinder), but if libunwind is +# built in the same cmake invocation as libcxx and we've got +# LIBCXXABI_USE_LLVM_UNWINDER set, we'd be linking against the just-built +# libunwind (and the compiler implicit -lunwind wouldn't succeed as the newly +# built libunwind isn't installed yet). For those cases, it'd be good to +# link with --uwnindlib=none. Check if that option works. +llvm_check_compiler_linker_flag(C "--unwindlib=none" LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG) +if (LIBCXX_SUPPORTS_UNWINDLIB_NONE_FLAG) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --unwindlib=none") +endif() + if(WIN32 AND NOT MINGW) # NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets # let the default linking take care of that. @@ -16,27 +29,44 @@ if (NOT LIBCXX_USE_COMPILER_RT) if(WIN32 AND NOT MINGW) set(LIBCXX_HAS_GCC_S_LIB NO) else() - check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB) + if(ANDROID) + check_library_exists(gcc __gcc_personality_v0 "" LIBCXX_HAS_GCC_LIB) + else() + check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB) + endif() endif() endif() -# libc++ is built with -nodefaultlibs, so we want all our checks to also -# use this option, otherwise we may end up with an inconsistency between +# libc++ is using -nostdlib++ at the link step when available, +# otherwise -nodefaultlibs is used. We want all our checks to also +# use one of these options, otherwise we may end up with an inconsistency between # the flags we think we require during configuration (if the checks are -# performed without -nodefaultlibs) and the flags that are actually -# required during compilation (which has the -nodefaultlibs). libc is +# performed without one of those options) and the flags that are actually +# required during compilation (which has the -nostdlib++ or -nodefaultlibs). libc is # required for the link to go through. We remove sanitizers from the # configuration checks to avoid spurious link errors. -check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) -if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs") + +check_c_compiler_flag(-nostdlib++ LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) +if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++") +else() + check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) + if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs") + endif() +endif() + +if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBCXX_HAS_C_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () if (LIBCXX_USE_COMPILER_RT) - list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) + include(HandleCompilerRT) + find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY + FLAGS ${LIBCXX_COMPILE_FLAGS}) list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}") + elseif (LIBCXX_HAS_GCC_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES gcc) elseif (LIBCXX_HAS_GCC_S_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s) endif () @@ -57,7 +87,7 @@ if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fsanitize-coverage=0") endif () endif () @@ -72,10 +102,6 @@ int main() { return 0; } cmake_pop_check_state() endif() -if(NOT WIN32 OR MINGW) - include(CheckLibcxxAtomic) -endif() - # Check libraries if(WIN32 AND NOT MINGW) # TODO(compnerd) do we want to support an emulation layer that allows for the @@ -84,14 +110,23 @@ if(WIN32 AND NOT MINGW) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_RT_LIB NO) set(LIBCXX_HAS_SYSTEM_LIB NO) + set(LIBCXX_HAS_ATOMIC_LIB NO) elseif(APPLE) check_library_exists(System write "" LIBCXX_HAS_SYSTEM_LIB) set(LIBCXX_HAS_PTHREAD_LIB NO) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_RT_LIB NO) + set(LIBCXX_HAS_ATOMIC_LIB NO) +elseif(FUCHSIA) + set(LIBCXX_HAS_M_LIB NO) + set(LIBCXX_HAS_PTHREAD_LIB NO) + set(LIBCXX_HAS_RT_LIB NO) + set(LIBCXX_HAS_SYSTEM_LIB NO) + check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB) else() check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB) check_library_exists(m ccos "" LIBCXX_HAS_M_LIB) check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB) set(LIBCXX_HAS_SYSTEM_LIB NO) + check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB) endif() diff --git a/docs/AddingNewCIJobs.rst b/docs/AddingNewCIJobs.rst new file mode 100644 index 000000000..613929ae1 --- /dev/null +++ b/docs/AddingNewCIJobs.rst @@ -0,0 +1,66 @@ +.. _AddingNewCIJobs: + +================== +Adding New CI Jobs +================== + +.. contents:: + :local: + +Adding The Job +============== + +libc++ uses Buildkite for running its CI. Setting up new CI jobs is easy, and +these jobs can run either on our existing infrastructure, or on your own. + +If you need to run the job on your own machines, please follow the +`Buildkite guide `_ to setup your +own agents. Make sure you tag your agents in a way that you'll be able +to recognize them when defining your job below. Finally, in order for the +agent to register itself to Buildkite, it will need a BuildKite Agent token. +Please contact a maintainer to get your token. + +Then, simply add a job to the Buildkite pipeline by editing ``libcxx/utils/ci/buildkite-pipeline.yml``. +Take a look at how the surrounding jobs are defined and do something similar. +An example of a job definition is: + +.. code-block:: yaml + + - label: "C++11" + command: "libcxx/utils/ci/run-buildbot generic-cxx11" + artifact_paths: + - "**/test-results.xml" + agents: + queue: "libcxx-builders" + os: "linux" + retry: + [...] + +If you create your own agents, put them in the ``libcxx-builders`` queue and +use agent tags to allow targetting your agents from the Buildkite pipeline +config appropriately. + +We try to keep the pipeline definition file as simple as possible, and to +keep any script used for CI inside ``libcxx/utils/ci``. This ensures that +it's possible to reproduce CI issues locally with ease, understanding of +course that some setups may require access to special hardware that is not +available. + +Testing Your New Job +==================== + +Testing your new job is easy -- once your agent is set up (if any), just open +a code review and the libc++ CI pipeline will run, including any changes you +might have made to the pipeline definition itself. + +Service Level Agreement +======================= + +To keep the libc++ CI useful for everyone, we aim for a quick turnaround time +for all CI jobs. This allows the overall pipeline to finish in a reasonable +amount of time, which is important because it directly affects our development +velocity. We also try to make sure that jobs run on reliable infrastructure in +order to avoid flaky failures, which reduce the value of CI for everyone. + +We may be reluctant to add and support CI jobs that take a long time to finish +or that are too flaky. diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst index e6a21a930..544d06cc8 100644 --- a/docs/BuildingLibcxx.rst +++ b/docs/BuildingLibcxx.rst @@ -9,114 +9,166 @@ Building libc++ .. _build instructions: -Getting Started -=============== +The instructions on this page are aimed at vendors who ship libc++ as part of an +operating system distribution, a toolchain or similar shipping vehicules. If you +are a user merely trying to use libc++ in your program, you most likely want to +refer to your vendor's documentation, or to the general documentation for using +libc++ :ref:`here `. -On Mac OS 10.7 (Lion) and later, the easiest way to get this library is to install -Xcode 4.2 or later. However if you want to install tip-of-trunk from here -(getting the bleeding edge), read on. - -The basic steps needed to build libc++ are: - -#. Checkout and configure LLVM (including libc++ and libc++abi), according to the `LLVM - getting started `_ documentation. Make sure - to include ``libcxx`` and ``libcxxabi`` in the ``LLVM_ENABLE_PROJECTS`` option passed - to CMake. - - For more information about configuring libc++ see :ref:`CMake Options`. - - * ``make cxx`` --- will build libc++ and libc++abi. - * ``make check-cxx check-cxxabi`` --- will run the test suites. - - Shared libraries for libc++ and libc++ abi should now be present in llvm/build/lib. - See :ref:`using an alternate libc++ installation ` - -#. **Optional**: Install libc++ and libc++abi - - If your system already provides a libc++ installation it is important to be - careful not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to - select a safe place to install libc++. - - * ``make install-cxx install-cxxabi`` --- Will install the libraries and the headers - - .. warning:: - * Replacing your systems libc++ installation could render the system non-functional. - * macOS will not boot without a valid copy of ``libc++.1.dylib`` in ``/usr/lib``. +.. warning:: + If your operating system already provides libc++, it is important to be careful + not to replace it. Replacing your system's libc++ installation could render it + non-functional. Use the CMake option ``CMAKE_INSTALL_PREFIX`` to select a safe + place to install libc++. -The instructions are for building libc++ on -FreeBSD, Linux, or Mac using `libc++abi`_ as the C++ ABI library. -On Linux, it is also possible to use :ref:`libsupc++ ` or libcxxrt. +The default build +================= -It is sometimes beneficial to build separately from the full LLVM build. An -out-of-tree build would look like this: +The default way of building libc++, libc++abi and libunwind is to root the CMake +invocation at ``/runtimes``. While those projects are under the LLVM +umbrella, they are different in nature from other build tools, so it makes sense +to treat them as a separate set of entities. The default build can be achieved +with the following CMake invocation: .. code-block:: bash - $ cd where-you-want-libcxx-to-live - $ # Check out the sources (includes everything, but we'll only use libcxx) - $ ``git clone https://github.com/llvm/llvm-project.git`` - $ cd where-you-want-to-build - $ mkdir build && cd build - $ export CC=clang CXX=clang++ - $ cmake -DLLVM_PATH=path/to/separate/llvm \ - -DLIBCXX_CXX_ABI=libcxxabi \ - -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/separate/libcxxabi/include \ - path/to/llvm-project/libcxx - $ make - $ make check-libcxx # optional + $ git clone https://github.com/llvm/llvm-project.git + $ cd llvm-project + $ mkdir build + $ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" # Configure + $ ninja -C build cxx cxxabi unwind # Build + $ ninja -C build check-cxx check-cxxabi check-unwind # Test + $ ninja -C build install-cxx install-cxxabi install-unwind # Install + +.. note:: + See :ref:`CMake Options` below for more configuration options. + +After building the various ``install-XXX`` targets, shared libraries for libc++, libc++abi and +libunwind should now be present in ``/lib``, and headers in +``/include/c++/v1``. See :ref:`using an alternate libc++ installation +` for information on how to use this libc++ over the default one. + +In the default configuration, the runtimes will be built using the compiler available by default +on your system. Of course, you can change what compiler is being used with the usual CMake +variables. If you wish to build the runtimes from a just-built Clang, the bootstrapping build +explained below makes this task easy. -Experimental Support for Windows --------------------------------- +Bootstrapping build +=================== -The Windows support requires building with clang-cl as cl does not support one -required extension: `#include_next`. Furthermore, VS 2015 or newer (19.00) is -required. In the case of clang-cl, we need to specify the "MS Compatibility -Version" as it defaults to 2014 (18.00). +It is possible to build Clang and then build the runtimes using that just-built compiler in a +single CMake invocation. This is usually the correct way to build the runtimes when putting together +a toolchain, or when the system compiler is not adequate to build them (too old, unsupported, etc.). +To do this, use the following CMake invocation, and in particular notice how we're now rooting the +CMake invocation at ``/llvm``: + +.. code-block:: bash + + $ mkdir build + $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ + -DLLVM_RUNTIME_TARGETS="" + $ ninja -C build runtimes # Build + $ ninja -C build check-runtimes # Test + $ ninja -C build install-runtimes # Install + +.. note:: + This type of build is also commonly called a "Runtimes build", but we would like to move + away from that terminology, which is too confusing. + +Support for Windows +=================== + +libcxx supports being built with clang-cl, but not with MSVC's cl.exe, as +cl doesn't support the ``#include_next`` extension. Furthermore, VS 2017 or +newer (19.14) is required. + +libcxx also supports being built with clang targeting MinGW environments. CMake + Visual Studio -~~~~~~~~~~~~~~~~~~~~~ +--------------------- Building with Visual Studio currently does not permit running tests. However, it is the simplest way to build. .. code-block:: batch - > cmake -G "Visual Studio 14 2015" ^ - -T "LLVM-vs2014" ^ - -DLIBCXX_ENABLE_SHARED=YES ^ - -DLIBCXX_ENABLE_STATIC=NO ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^ - \path\to\libcxx - > cmake --build . + > cmake -G "Visual Studio 16 2019" -S libcxx -B build ^ + -T "ClangCL" ^ + -DLIBCXX_ENABLE_SHARED=YES ^ + -DLIBCXX_ENABLE_STATIC=NO ^ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO + > cmake --build build -CMake + ninja -~~~~~~~~~~~~~ +CMake + ninja (MSVC) +-------------------- Building with ninja is required for development to enable tests. -Unfortunately, doing so requires additional configuration as we cannot -just specify a toolset. +A couple of tests require Bash to be available, and a couple dozens +of tests require other posix tools (cp, grep and similar - LLVM's tests +require the same). Without those tools the vast majority of tests +can still be ran successfully. + +If Git for Windows is available, that can be used to provide the bash +shell by adding the right bin directory to the path, e.g. +``set PATH=%PATH%;C:\Program Files\Git\usr\bin``. + +Alternatively, one can also choose to run the whole build in a MSYS2 +shell. That can be set up e.g. by starting a Visual Studio Tools Command +Prompt (for getting the environment variables pointing to the headers and +import libraries), and making sure that clang-cl is available in the +path. From there, launch an MSYS2 shell via e.g. +``C:\msys64\msys2_shell.cmd -full-path -mingw64`` (preserving the earlier +environment, allowing the MSVC headers/libraries and clang-cl to be found). + +In either case, then run: .. code-block:: batch - > cmake -G Ninja ^ - -DCMAKE_MAKE_PROGRAM=/path/to/ninja ^ - -DCMAKE_SYSTEM_NAME=Windows ^ + > cmake -G Ninja -S libcxx -B build ^ -DCMAKE_C_COMPILER=clang-cl ^ - -DCMAKE_C_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^ - -DCMAKE_CXX_COMPILER=clang-cl ^ - -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 --target=i686--windows" ^ - -DLLVM_PATH=/path/to/llvm/tree ^ - -DLIBCXX_ENABLE_SHARED=YES ^ - -DLIBCXX_ENABLE_STATIC=NO ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^ - \path\to\libcxx - > /path/to/ninja cxx - > /path/to/ninja check-cxx + -DCMAKE_CXX_COMPILER=clang-cl ^ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO + > ninja -C build cxx + > ninja -C build check-cxx -Note that the paths specified with backward slashes must use the `\\` as the -directory separator as clang-cl may otherwise parse the path as an argument. +If you are running in an MSYS2 shell and you have installed the +MSYS2-provided clang package (which defaults to a non-MSVC target), you +should add e.g. ``-DLIBCXX_TARGET_TRIPLE=x86_64-windows-msvc`` (replacing +``x86_64`` with the architecture you're targeting) to the ``cmake`` command +line above. This will instruct ``check-cxx`` to use the right target triple +when invoking ``clang++``. + +Also note that if not building in Release mode, a failed assert in the tests +pops up a blocking dialog box, making it hard to run a larger number of tests. + +CMake + ninja (MinGW) +--------------------- + +libcxx can also be built in MinGW environments, e.g. with the MinGW +compilers in MSYS2. This requires clang to be available (installed with +e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja. + +.. code-block:: bash + + > cmake -G Ninja -S libcxx -B build \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DLIBCXX_HAS_WIN32_THREAD_API=ON \ + -DLIBCXX_CXX_ABI=libstdc++ \ + -DLIBCXX_TARGET_INFO="libcxx.test.target_info.MingwLocalTI" + > ninja -C build cxx + > cp /mingw64/bin/{libstdc++-6,libgcc_s_seh-1,libwinpthread-1}.dll lib + > ninja -C build check-cxx + +As this build configuration ends up depending on a couple other DLLs that +aren't available in path while running tests, copy them into the same +directory as the tested libc++ DLL. + +(Building a libc++ that depends on libstdc++ isn't necessarily a config one +would want to deploy, but it simplifies the config for testing purposes.) .. _`libc++abi`: http://libcxxabi.llvm.org/ @@ -162,15 +214,9 @@ libc++ specific options .. option:: LIBCXX_ENABLE_ASSERTIONS:BOOL - **Default**: ``ON`` - - Build libc++ with assertions enabled. - -.. option:: LIBCXX_BUILD_32_BITS:BOOL - **Default**: ``OFF`` - Build libc++ as a 32 bit library. Also see `LLVM_BUILD_32_BITS`. + Build libc++ with assertions enabled. .. option:: LIBCXX_ENABLE_SHARED:BOOL @@ -191,12 +237,6 @@ libc++ specific options Extra suffix to append to the directory where libraries are to be installed. This option overrides `LLVM_LIBDIR_SUFFIX`. -.. option:: LIBCXX_INSTALL_PREFIX:STRING - - **Default**: ``""`` - - Define libc++ destination prefix. - .. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL **Default**: ``OFF`` @@ -208,10 +248,50 @@ libc++ specific options .. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL - **Default**: ``ON`` except on Windows. + **Default**: ``ON`` except on Windows when using MSVC. This option can be used to enable or disable the filesystem components on - platforms that may not support them. For example on Windows. + platforms that may not support them. For example on Windows when using MSVC. + +.. option:: LIBCXX_ENABLE_WIDE_CHARACTERS:BOOL + + **Default**: ``ON`` + + This option can be used to disable support for ``wchar_t`` in the library. It also + allows the library to work on top of a C Standard Library that does not provide + support for ``wchar_t``. This is especially useful in embedded settings where + C Standard Libraries don't always provide all the usual bells and whistles. + +.. option:: LIBCXX_ENABLE_INCOMPLETE_FEATURES:BOOL + + **Default**: ``ON`` + + Whether to enable support for incomplete library features. Incomplete features + are new library features under development. These features don't guarantee + ABI stability nor the quality of completed library features. Vendors + shipping the library may want to disable this option. + +.. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH + + **Default**: ``lib${LIBCXX_LIBDIR_SUFFIX}`` + + Path where built libc++ libraries should be installed. If a relative path, + relative to ``CMAKE_INSTALL_PREFIX``. + +.. option:: LIBCXX_INSTALL_INCLUDE_DIR:PATH + + **Default**: ``include/c++/v1`` + + Path where target-agnostic libc++ headers should be installed. If a relative + path, relative to ``CMAKE_INSTALL_PREFIX``. + +.. option:: LIBCXX_INSTALL_INCLUDE_TARGET_DIR:PATH + + **Default**: ``include/c++/v1`` or + ``include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1`` + + Path where target-specific libc++ headers should be installed. If a relative + path, relative to ``CMAKE_INSTALL_PREFIX``. .. _libc++experimental options: @@ -238,7 +318,7 @@ ABI Library Specific Options .. option:: LIBCXX_CXX_ABI:STRING - **Values**: ``none``, ``libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``. + **Values**: ``none``, ``libcxxabi``, ``system-libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``. Select the ABI library to build libc++ against. @@ -290,7 +370,7 @@ libc++ Feature Options .. option:: LIBCXX_INCLUDE_TESTS:BOOL - **Default**: ``ON`` (or value of ``LLVM_INCLUDE_DIR``) + **Default**: ``ON`` (or value of ``LLVM_INCLUDE_TESTS``) Build the libc++ tests. @@ -376,20 +456,6 @@ The following options allow building libc++ for a different ABI version. See ``include/__config`` for the list of ABI macros. -.. option:: LIBCXX_HAS_MERGED_TYPEINFO_NAMES_DEFAULT - - **Default**: ``None``. When defined this option overrides the libraries default configuration - for whether merged type info names are present. - - - Build ``std::type_info`` with the assumption that type info names for a type have been fully - merged are unique across the entire program. This may not be the case for libraries built with - ``-Bsymbolic`` or due to compiler or linker bugs (Ex. llvm.org/PR37398). - - When the value is ``ON`` typeinfo comparisons compare only the pointer value, otherwise ``strcmp`` - is used as a fallback. - - .. _LLVM-specific variables: LLVM-specific options @@ -416,8 +482,12 @@ LLVM-specific options Using Alternate ABI libraries ============================= +In order to implement various features like exceptions, RTTI, ``dynamic_cast`` and +more, libc++ requires what we refer to as an ABI library. Typically, that library +implements the `Itanium C++ ABI `_. -.. _libsupcxx: +By default, libc++ uses libc++abi as an ABI library. However, it is possible to use +other ABI libraries too. Using libsupc++ on Linux ------------------------ @@ -447,17 +517,17 @@ You can also figure this out by running End of search list. Note that the first two entries happen to be what we are looking for. This -may not be correct on other platforms. +may not be correct on all platforms. We can now run CMake: .. code-block:: bash - $ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \ - -DLIBCXX_CXX_ABI=libstdc++ \ - -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \ - + $ cmake -G Ninja -S runtimes -B build \ + -DLLVM_ENABLE_RUNTIMES="libcxx" \ + -DLIBCXX_CXX_ABI=libstdc++ \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" + $ ninja -C build install-cxx You can also substitute ``-DLIBCXX_CXX_ABI=libsupc++`` @@ -468,16 +538,6 @@ GCC ships libsupc++ separately but only as a static library. If a program also needs to link against libstdc++, it will provide its own copy of libsupc++ and this can lead to subtle problems. -.. code-block:: bash - - $ make cxx - $ make install - -You can now run clang with -stdlib=libc++. - - -.. _libcxxrt_ref: - Using libcxxrt on Linux ------------------------ @@ -489,14 +549,11 @@ We can now run CMake like: .. code-block:: bash - $ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \ - -DLIBCXX_CXX_ABI=libcxxrt \ - -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - - $ make cxx - $ make install + $ cmake -G Ninja -S runtimes -B build \ + -DLLVM_ENABLE_RUNTIMES="libcxx" \ + -DLIBCXX_CXX_ABI=libcxxrt \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src + $ ninja -C build install-cxx Unfortunately you can't simply run clang with "-stdlib=libc++" at this point, as clang is set up to link for libc++ linked to libsupc++. To get around this @@ -514,32 +571,4 @@ situations will give the same result: $ clang++ -stdlib=libc++ helloworld.cpp -lcxxrt -.. _`libcxxrt`: https://github.com/pathscale/libcxxrt/ - - -Using a local ABI library installation ---------------------------------------- - -.. warning:: - This is not recommended in almost all cases. - -These instructions should only be used when you can't install your ABI library. - -Normally you must link libc++ against a ABI shared library that the -linker can find. If you want to build and test libc++ against an ABI -library not in the linker's path you need to set -``-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib`` when configuring CMake. - -An example build using libc++abi would look like: - -.. code-block:: bash - - $ CC=clang CXX=clang++ cmake \ - -DLIBCXX_CXX_ABI=libc++abi \ - -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/path/to/libcxxabi/include" \ - -DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib" \ - path/to/libcxx - $ make - -When testing libc++ LIT will automatically link against the proper ABI -library. +.. _`libcxxrt`: https://github.com/libcxxrt/libcxxrt diff --git a/docs/Contributing.rst b/docs/Contributing.rst new file mode 100644 index 000000000..3f9ea9c3a --- /dev/null +++ b/docs/Contributing.rst @@ -0,0 +1,181 @@ +.. _ContributingToLibcxx: + +====================== +Contributing to libc++ +====================== + +This file contains notes about various tasks and processes specific to contributing +to libc++. If this is your first time contributing, please also read `this document +`__ on general rules for contributing to LLVM. + +For libc++, please make sure you follow `these instructions `_ +for submitting a code review from the command-line using ``arc``, since we have some +automation (e.g. CI) that depends on the review being submitted that way. + +If you plan on contributing to libc++, it can be useful to join the ``#libcxx`` channel +on `LLVM's Discord server `__. + +Looking for pre-existing reviews +================================ + +Before you start working on any feature, please take a look at the open reviews +to avoid duplicating someone else's work. You can do that by going to the website +where code reviews are held, `Differential `__, +and clicking on ``Libc++ Open Reviews`` in the sidebar to the left. If you see +that your feature is already being worked on, please consider chiming in instead +of duplicating work! + +Pre-commit check list +===================== + +Before committing or creating a review, please go through this check-list to make +sure you don't forget anything: + +- Do you have tests for every public class and/or function you're adding or modifying? +- Did you update the synopsis of the relevant headers? +- Did you update the relevant files to track implementation status (in ``docs/Status/``)? +- Did you mark all functions and type declarations with the :ref:`proper visibility macro `? +- If you added a header: + + - Did you add it to ``include/module.modulemap``? + - Did you add it to ``include/CMakeLists.txt``? + - If it's a public header, did you add a test under ``test/libcxx`` that the new header defines ``_LIBCPP_VERSION``? See ``test/libcxx/algorithms/version.pass.cpp`` for an example. NOTE: This should be automated. + - If it's a public header, did you update ``utils/generate_header_inclusion_tests.py``? + +- Did you add the relevant feature test macro(s) for your feature? Did you update the ``generate_feature_test_macro_components.py`` script with it? +- Did you run the ``libcxx-generate-files`` target and verify its output? + +The review process +================== + +After uploading your patch, you should see that the "libc++" review group is automatically +added as a reviewer for your patch. Once the group is marked as having approved your patch, +you can commit it. However, if you get an approval very quickly for a significant patch, +please try to wait a couple of business days before committing to give the opportunity for +other reviewers to chime in. If you need someone else to commit the patch for you, please +mention it and provide your ``Name `` for us to attribute the commit properly. + +Note that the rule for accepting as the "libc++" review group is to wait for two members +of the group to have approved the patch, excluding the patch author. This is not a hard +rule -- for very simple patches, use your judgement. The `"libc++" review group `__ +consists of frequent libc++ contributors with a good understanding of the project's +guidelines -- if you would like to be added to it, please reach out on Discord. + +Post-release check list +======================= + +After branching for an LLVM release: + +1. Update ``_LIBCPP_VERSION`` in ``include/__config`` +2. Update the ``include/__libcpp_version`` file +3. Update the version number in ``docs/conf.py`` + +Exporting new symbols from the library +====================================== + +When exporting new symbols from libc++, you must update the ABI lists located in ``lib/abi``. +To test whether the lists are up-to-date, please run the target ``check-cxx-abilist``. +To regenerate the lists, use the target ``generate-cxx-abilist``. +The ABI lists must be updated for all supported platforms; currently Linux and +Apple. If you don't have access to one of these platforms, you can download an +updated list from the failed build at +`Buildkite `__. +Look for the failed build and select the ``artifacts`` tab. There, download the +abilist for the platform, e.g.: + +* C++20 for the Linux platform. +* MacOS C++20 for the Apple platform. + +Working on large features +========================= + +Libc++ makes no guarantees about the implementation status or the ABI stability +of features that have not yet been ratified in the C++ Standard. After the C++ +Standard is ratified libc++ promises a conforming and ABI-stable +implementation. When working on a large new feature in the ratified version of +the C++ Standard that can't be finished before the next release branch is +created, we can't honor this promise. Another reason for not being able to +promise ABI stability happens when the C++ Standard committee retroactively +accepts ABI breaking papers as defect reports against the ratified C++ +Standard. + +When working on these features it should be possible for libc++ vendors to +disable these incomplete features, so they can promise ABI stability to their +customers. This is done by the CMake option +``LIBCXX_ENABLE_INCOMPLETE_FEATURES``. When start working on a large feature +the following steps are required to guard the new library with the CMake +option. + +* ``libcxx/CMakeLists.txt``: Add + + .. code-block:: cmake + + config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FOO) + +* ``libcxx/include/__config_site.in``: Add + + .. code-block:: c++ + + #cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FOO + +* ``libcxx/include/foo``: The contents of the file should be guarded in an + ``ifdef`` and always include ```` + + .. code-block:: c++ + + #ifndef _LIBCPP_FOO + #define _LIBCPP_FOO + + // Make sure all feature-test macros are available. + #include + // Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. + #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FOO) + + ... + + #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FO0) + #endif // _LIBCPP_FOO + +* ``libcxx/src/CMakeLists.txt``: When the library has a file ``foo.cpp`` it + should only be added when ``LIBCXX_ENABLE_INCOMPLETE_FEATURES`` is enabled + + .. code-block:: cmake + + if(LIBCXX_ENABLE_INCOMPLETE_FEATURES) + list(APPEND LIBCXX_SOURCES + foo.cpp + ) + endif() + +* ``libcxx/utils/generate_feature_test_macro_components.py``: Add to + ``lit_markup`` + + .. code-block:: python + + "foo": ["UNSUPPORTED: libcpp-has-no-incomplete-foo"], + +* ``libcxx/utils/generate_header_inclusion_tests.py``: Add to ``lit_markup`` + + .. code-block:: python + + "foo": ["UNSUPPORTED: libcpp-has-no-incomplete-foo"], + +* ``libcxx/utils/generate_header_tests.py``: Add to ``header_markup`` + + .. code-block:: python + + "foo": ["ifndef _LIBCPP_HAS_NO_INCOMPLETE_FOO"], + +* ``libcxx/utils/libcxx/test/features.py``: Add to ``macros`` + + .. code-block:: python + + '_LIBCPP_HAS_NO_INCOMPLETE_FOO': 'libcpp-has-no-incomplete-foo', + +* All tests that include ```` should contain + + .. code-block:: c++ + + // UNSUPPORTED: libcpp-has-no-incomplete-foo + +Once the library is complete these changes and guards should be removed. diff --git a/docs/DesignDocs/ABIVersioning.rst b/docs/DesignDocs/ABIVersioning.rst index 5960dd186..3b82f3cc6 100644 --- a/docs/DesignDocs/ABIVersioning.rst +++ b/docs/DesignDocs/ABIVersioning.rst @@ -3,15 +3,22 @@ Libc++ ABI stability ==================== -Libc++ aims to preserve stable ABI to avoid subtle bugs when code built to the old ABI -is linked with the code build to the new ABI. At the same time, libc++ allows ABI-breaking -improvements and bugfixes for the scenarios when ABI change is not a issue. +Libc++ aims to preserve a stable ABI to avoid subtle bugs when code built under the old ABI +is linked with code built under the new ABI. At the same time, libc++ wants to make +ABI-breaking improvements and bugfixes in scenarios where the user doesn't mind ABI breaks. -To support both cases, libc++ allows specifying the ABI version at the -build time. The version is defined with a cmake option -LIBCXX_ABI_VERSION. Another option LIBCXX_ABI_UNSTABLE can be used to -include all present ABI breaking features. These options translate -into C++ macro definitions _LIBCPP_ABI_VERSION, _LIBCPP_ABI_UNSTABLE. +To support both cases, libc++ allows specifying an ABI version at +build time. The version is defined with CMake option ``LIBCXX_ABI_VERSION``. +Currently supported values are ``1`` (the stable default) +and ``2`` (the unstable "next" version). At some point "ABI version 2" will be +frozen and new ABI-breaking changes will start being applied to version ``3``; +but this has not happened yet. -Any ABI-changing feature is placed under it's own macro, _LIBCPP_ABI_XXX, which is enabled -based on the value of _LIBCPP_ABI_VERSION. _LIBCPP_ABI_UNSTABLE, if set, enables all features at once. +To always use the most cutting-edge, most unstable ABI (which is currently ``2`` +but at some point will become ``3``), set the CMake option ``LIBCXX_ABI_UNSTABLE``. + +Internally, each ABI-changing feature is placed under its own C++ macro, +``_LIBCPP_ABI_XXX``. These macros' definitions are controlled by the C++ macro +``_LIBCPP_ABI_VERSION``, which is controlled by the ``LIBCXX_ABI_VERSION`` set +at build time. Libc++ does not intend users to interact with these C++ macros +directly. diff --git a/docs/DesignDocs/AtomicDesign.rst b/docs/DesignDocs/AtomicDesign.rst new file mode 100644 index 000000000..4b28ab2a8 --- /dev/null +++ b/docs/DesignDocs/AtomicDesign.rst @@ -0,0 +1,797 @@ + +==================== +```` Design +==================== + +There were originally 3 designs under consideration. They differ in where most +of the implementation work is done. The functionality exposed to the customer +should be identical (and conforming) for all three designs. + + +Design A: Minimal work for the library +====================================== +The compiler supplies all of the intrinsics as described below. This list of +intrinsics roughly parallels the requirements of the C and C++ atomics proposals. +The C and C++ library implementations simply drop through to these intrinsics. +Anything the platform does not support in hardware, the compiler +arranges for a (compiler-rt) library call to be made which will do the job with +a mutex, and in this case ignoring the memory ordering parameter (effectively +implementing ``memory_order_seq_cst``). + +Ultimate efficiency is preferred over run time error checking. Undefined +behavior is acceptable when the inputs do not conform as defined below. + +.. code-block:: cpp + + // In every intrinsic signature below, type* atomic_obj may be a pointer to a + // volatile-qualified type. Memory ordering values map to the following meanings: + // memory_order_relaxed == 0 + // memory_order_consume == 1 + // memory_order_acquire == 2 + // memory_order_release == 3 + // memory_order_acq_rel == 4 + // memory_order_seq_cst == 5 + + // type must be trivially copyable + // type represents a "type argument" + bool __atomic_is_lock_free(type); + + // type must be trivially copyable + // Behavior is defined for mem_ord = 0, 1, 2, 5 + type __atomic_load(const type* atomic_obj, int mem_ord); + + // type must be trivially copyable + // Behavior is defined for mem_ord = 0, 3, 5 + void __atomic_store(type* atomic_obj, type desired, int mem_ord); + + // type must be trivially copyable + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_exchange(type* atomic_obj, type desired, int mem_ord); + + // type must be trivially copyable + // Behavior is defined for mem_success = [0 ... 5], + // mem_failure <= mem_success + // mem_failure != 3 + // mem_failure != 4 + bool __atomic_compare_exchange_strong(type* atomic_obj, + type* expected, type desired, + int mem_success, int mem_failure); + + // type must be trivially copyable + // Behavior is defined for mem_success = [0 ... 5], + // mem_failure <= mem_success + // mem_failure != 3 + // mem_failure != 4 + bool __atomic_compare_exchange_weak(type* atomic_obj, + type* expected, type desired, + int mem_success, int mem_failure); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_fetch_add(type* atomic_obj, type operand, int mem_ord); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_fetch_sub(type* atomic_obj, type operand, int mem_ord); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_fetch_and(type* atomic_obj, type operand, int mem_ord); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_fetch_or(type* atomic_obj, type operand, int mem_ord); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + // Behavior is defined for mem_ord = [0 ... 5] + type __atomic_fetch_xor(type* atomic_obj, type operand, int mem_ord); + + // Behavior is defined for mem_ord = [0 ... 5] + void* __atomic_fetch_add(void** atomic_obj, ptrdiff_t operand, int mem_ord); + void* __atomic_fetch_sub(void** atomic_obj, ptrdiff_t operand, int mem_ord); + + // Behavior is defined for mem_ord = [0 ... 5] + void __atomic_thread_fence(int mem_ord); + void __atomic_signal_fence(int mem_ord); + +If desired the intrinsics taking a single ``mem_ord`` parameter can default +this argument to 5. + +If desired the intrinsics taking two ordering parameters can default ``mem_success`` +to 5, and ``mem_failure`` to ``translate_memory_order(mem_success)`` where +``translate_memory_order(mem_success)`` is defined as: + +.. code-block:: cpp + + int translate_memory_order(int o) { + switch (o) { + case 4: + return 2; + case 3: + return 0; + } + return o; + } + +Below are representative C++ implementations of all of the operations. Their +purpose is to document the desired semantics of each operation, assuming +``memory_order_seq_cst``. This is essentially the code that will be called +if the front end calls out to compiler-rt. + +.. code-block:: cpp + + template + T __atomic_load(T const volatile* obj) { + unique_lock _(some_mutex); + return *obj; + } + + template + void __atomic_store(T volatile* obj, T desr) { + unique_lock _(some_mutex); + *obj = desr; + } + + template + T __atomic_exchange(T volatile* obj, T desr) { + unique_lock _(some_mutex); + T r = *obj; + *obj = desr; + return r; + } + + template + bool __atomic_compare_exchange_strong(T volatile* obj, T* exp, T desr) { + unique_lock _(some_mutex); + if (std::memcmp(const_cast(obj), exp, sizeof(T)) == 0) // if (*obj == *exp) + { + std::memcpy(const_cast(obj), &desr, sizeof(T)); // *obj = desr; + return true; + } + std::memcpy(exp, const_cast(obj), sizeof(T)); // *exp = *obj; + return false; + } + + // May spuriously return false (even if *obj == *exp) + template + bool __atomic_compare_exchange_weak(T volatile* obj, T* exp, T desr) { + unique_lock _(some_mutex); + if (std::memcmp(const_cast(obj), exp, sizeof(T)) == 0) // if (*obj == *exp) + { + std::memcpy(const_cast(obj), &desr, sizeof(T)); // *obj = desr; + return true; + } + std::memcpy(exp, const_cast(obj), sizeof(T)); // *exp = *obj; + return false; + } + + template + T __atomic_fetch_add(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj += operand; + return r; + } + + template + T __atomic_fetch_sub(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj -= operand; + return r; + } + + template + T __atomic_fetch_and(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj &= operand; + return r; + } + + template + T __atomic_fetch_or(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj |= operand; + return r; + } + + template + T __atomic_fetch_xor(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj ^= operand; + return r; + } + + void* __atomic_fetch_add(void* volatile* obj, ptrdiff_t operand) { + unique_lock _(some_mutex); + void* r = *obj; + (char*&)(*obj) += operand; + return r; + } + + void* __atomic_fetch_sub(void* volatile* obj, ptrdiff_t operand) { + unique_lock _(some_mutex); + void* r = *obj; + (char*&)(*obj) -= operand; + return r; + } + + void __atomic_thread_fence() { + unique_lock _(some_mutex); + } + + void __atomic_signal_fence() { + unique_lock _(some_mutex); + } + + +Design B: Something in between +============================== +This is a variation of design A which puts the burden on the library to arrange +for the correct manipulation of the run time memory ordering arguments, and only +calls the compiler for well-defined memory orderings. I think of this design as +the worst of A and C, instead of the best of A and C. But I offer it as an +option in the spirit of completeness. + +.. code-block:: cpp + + // type must be trivially copyable + bool __atomic_is_lock_free(const type* atomic_obj); + + // type must be trivially copyable + type __atomic_load_relaxed(const volatile type* atomic_obj); + type __atomic_load_consume(const volatile type* atomic_obj); + type __atomic_load_acquire(const volatile type* atomic_obj); + type __atomic_load_seq_cst(const volatile type* atomic_obj); + + // type must be trivially copyable + type __atomic_store_relaxed(volatile type* atomic_obj, type desired); + type __atomic_store_release(volatile type* atomic_obj, type desired); + type __atomic_store_seq_cst(volatile type* atomic_obj, type desired); + + // type must be trivially copyable + type __atomic_exchange_relaxed(volatile type* atomic_obj, type desired); + type __atomic_exchange_consume(volatile type* atomic_obj, type desired); + type __atomic_exchange_acquire(volatile type* atomic_obj, type desired); + type __atomic_exchange_release(volatile type* atomic_obj, type desired); + type __atomic_exchange_acq_rel(volatile type* atomic_obj, type desired); + type __atomic_exchange_seq_cst(volatile type* atomic_obj, type desired); + + // type must be trivially copyable + bool __atomic_compare_exchange_strong_relaxed_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_consume_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_consume_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acquire_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acquire_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acquire_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_release_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_release_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_release_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acq_rel_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acq_rel_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_acq_rel_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_seq_cst_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_seq_cst_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_seq_cst_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_strong_seq_cst_seq_cst(volatile type* atomic_obj, + type* expected, + type desired); + + // type must be trivially copyable + bool __atomic_compare_exchange_weak_relaxed_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_consume_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_consume_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acquire_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acquire_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acquire_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_release_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_release_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_release_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acq_rel_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acq_rel_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_acq_rel_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_seq_cst_relaxed(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_seq_cst_consume(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_seq_cst_acquire(volatile type* atomic_obj, + type* expected, + type desired); + bool __atomic_compare_exchange_weak_seq_cst_seq_cst(volatile type* atomic_obj, + type* expected, + type desired); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + type __atomic_fetch_add_relaxed(volatile type* atomic_obj, type operand); + type __atomic_fetch_add_consume(volatile type* atomic_obj, type operand); + type __atomic_fetch_add_acquire(volatile type* atomic_obj, type operand); + type __atomic_fetch_add_release(volatile type* atomic_obj, type operand); + type __atomic_fetch_add_acq_rel(volatile type* atomic_obj, type operand); + type __atomic_fetch_add_seq_cst(volatile type* atomic_obj, type operand); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + type __atomic_fetch_sub_relaxed(volatile type* atomic_obj, type operand); + type __atomic_fetch_sub_consume(volatile type* atomic_obj, type operand); + type __atomic_fetch_sub_acquire(volatile type* atomic_obj, type operand); + type __atomic_fetch_sub_release(volatile type* atomic_obj, type operand); + type __atomic_fetch_sub_acq_rel(volatile type* atomic_obj, type operand); + type __atomic_fetch_sub_seq_cst(volatile type* atomic_obj, type operand); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + type __atomic_fetch_and_relaxed(volatile type* atomic_obj, type operand); + type __atomic_fetch_and_consume(volatile type* atomic_obj, type operand); + type __atomic_fetch_and_acquire(volatile type* atomic_obj, type operand); + type __atomic_fetch_and_release(volatile type* atomic_obj, type operand); + type __atomic_fetch_and_acq_rel(volatile type* atomic_obj, type operand); + type __atomic_fetch_and_seq_cst(volatile type* atomic_obj, type operand); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + type __atomic_fetch_or_relaxed(volatile type* atomic_obj, type operand); + type __atomic_fetch_or_consume(volatile type* atomic_obj, type operand); + type __atomic_fetch_or_acquire(volatile type* atomic_obj, type operand); + type __atomic_fetch_or_release(volatile type* atomic_obj, type operand); + type __atomic_fetch_or_acq_rel(volatile type* atomic_obj, type operand); + type __atomic_fetch_or_seq_cst(volatile type* atomic_obj, type operand); + + // type is one of: char, signed char, unsigned char, short, unsigned short, int, + // unsigned int, long, unsigned long, long long, unsigned long long, + // char16_t, char32_t, wchar_t + type __atomic_fetch_xor_relaxed(volatile type* atomic_obj, type operand); + type __atomic_fetch_xor_consume(volatile type* atomic_obj, type operand); + type __atomic_fetch_xor_acquire(volatile type* atomic_obj, type operand); + type __atomic_fetch_xor_release(volatile type* atomic_obj, type operand); + type __atomic_fetch_xor_acq_rel(volatile type* atomic_obj, type operand); + type __atomic_fetch_xor_seq_cst(volatile type* atomic_obj, type operand); + + void* __atomic_fetch_add_relaxed(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_add_consume(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_add_acquire(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_add_release(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_add_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_add_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand); + + void* __atomic_fetch_sub_relaxed(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_sub_consume(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_sub_acquire(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_sub_release(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_sub_acq_rel(void* volatile* atomic_obj, ptrdiff_t operand); + void* __atomic_fetch_sub_seq_cst(void* volatile* atomic_obj, ptrdiff_t operand); + + void __atomic_thread_fence_relaxed(); + void __atomic_thread_fence_consume(); + void __atomic_thread_fence_acquire(); + void __atomic_thread_fence_release(); + void __atomic_thread_fence_acq_rel(); + void __atomic_thread_fence_seq_cst(); + + void __atomic_signal_fence_relaxed(); + void __atomic_signal_fence_consume(); + void __atomic_signal_fence_acquire(); + void __atomic_signal_fence_release(); + void __atomic_signal_fence_acq_rel(); + void __atomic_signal_fence_seq_cst(); + +Design C: Minimal work for the front end +======================================== +The ```` header is one of the most closely coupled headers to the compiler. +Ideally when you invoke any function from ````, it should result in highly +optimized assembly being inserted directly into your application -- assembly that +is not otherwise representable by higher level C or C++ expressions. The design of +the libc++ ```` header started with this goal in mind. A secondary, but +still very important goal is that the compiler should have to do minimal work to +facilitate the implementation of ````. Without this second goal, then +practically speaking, the libc++ ```` header would be doomed to be a +barely supported, second class citizen on almost every platform. + +Goals: + +- Optimal code generation for atomic operations +- Minimal effort for the compiler to achieve goal 1 on any given platform +- Conformance to the C++0X draft standard + +The purpose of this document is to inform compiler writers what they need to do +to enable a high performance libc++ ```` with minimal effort. + +The minimal work that must be done for a conforming ```` +---------------------------------------------------------------- +The only "atomic" operations that must actually be lock free in +```` are represented by the following compiler intrinsics: + +.. code-block:: cpp + + __atomic_flag__ __atomic_exchange_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) { + unique_lock _(some_mutex); + __atomic_flag__ result = *obj; + *obj = desr; + return result; + } + + void __atomic_store_seq_cst(__atomic_flag__ volatile* obj, __atomic_flag__ desr) { + unique_lock _(some_mutex); + *obj = desr; + } + +Where: + +- If ``__has_feature(__atomic_flag)`` evaluates to 1 in the preprocessor then + the compiler must define ``__atomic_flag__`` (e.g. as a typedef to ``int``). +- If ``__has_feature(__atomic_flag)`` evaluates to 0 in the preprocessor then + the library defines ``__atomic_flag__`` as a typedef to ``bool``. +- To communicate that the above intrinsics are available, the compiler must + arrange for ``__has_feature`` to return 1 when fed the intrinsic name + appended with an '_' and the mangled type name of ``__atomic_flag__``. + +For example if ``__atomic_flag__`` is ``unsigned int``: + +.. code-block:: cpp + + // __has_feature(__atomic_flag) == 1 + // __has_feature(__atomic_exchange_seq_cst_j) == 1 + // __has_feature(__atomic_store_seq_cst_j) == 1 + + typedef unsigned int __atomic_flag__; + + unsigned int __atomic_exchange_seq_cst(unsigned int volatile*, unsigned int) { + // ... + } + + void __atomic_store_seq_cst(unsigned int volatile*, unsigned int) { + // ... + } + +That's it! Compiler writers do the above and you've got a fully conforming +(though sub-par performance) ```` header! + + +Recommended work for a higher performance ```` +------------------------------------------------------ +It would be good if the above intrinsics worked with all integral types plus +``void*``. Because this may not be possible to do in a lock-free manner for +all integral types on all platforms, a compiler must communicate each type that +an intrinsic works with. For example, if ``__atomic_exchange_seq_cst`` works +for all types except for ``long long`` and ``unsigned long long`` then: + +.. code-block:: cpp + + __has_feature(__atomic_exchange_seq_cst_b) == 1 // bool + __has_feature(__atomic_exchange_seq_cst_c) == 1 // char + __has_feature(__atomic_exchange_seq_cst_a) == 1 // signed char + __has_feature(__atomic_exchange_seq_cst_h) == 1 // unsigned char + __has_feature(__atomic_exchange_seq_cst_Ds) == 1 // char16_t + __has_feature(__atomic_exchange_seq_cst_Di) == 1 // char32_t + __has_feature(__atomic_exchange_seq_cst_w) == 1 // wchar_t + __has_feature(__atomic_exchange_seq_cst_s) == 1 // short + __has_feature(__atomic_exchange_seq_cst_t) == 1 // unsigned short + __has_feature(__atomic_exchange_seq_cst_i) == 1 // int + __has_feature(__atomic_exchange_seq_cst_j) == 1 // unsigned int + __has_feature(__atomic_exchange_seq_cst_l) == 1 // long + __has_feature(__atomic_exchange_seq_cst_m) == 1 // unsigned long + __has_feature(__atomic_exchange_seq_cst_Pv) == 1 // void* + +Note that only the ``__has_feature`` flag is decorated with the argument +type. The name of the compiler intrinsic is not decorated, but instead works +like a C++ overloaded function. + +Additionally, there are other intrinsics besides ``__atomic_exchange_seq_cst`` +and ``__atomic_store_seq_cst``. They are optional. But if the compiler can +generate faster code than provided by the library, then clients will benefit +from the compiler writer's expertise and knowledge of the targeted platform. + +Below is the complete list of *sequentially consistent* intrinsics, and +their library implementations. Template syntax is used to indicate the desired +overloading for integral and ``void*`` types. The template does not represent a +requirement that the intrinsic operate on **any** type! + +.. code-block:: cpp + + // T is one of: + // bool, char, signed char, unsigned char, short, unsigned short, + // int, unsigned int, long, unsigned long, + // long long, unsigned long long, char16_t, char32_t, wchar_t, void* + + template + T __atomic_load_seq_cst(T const volatile* obj) { + unique_lock _(some_mutex); + return *obj; + } + + template + void __atomic_store_seq_cst(T volatile* obj, T desr) { + unique_lock _(some_mutex); + *obj = desr; + } + + template + T __atomic_exchange_seq_cst(T volatile* obj, T desr) { + unique_lock _(some_mutex); + T r = *obj; + *obj = desr; + return r; + } + + template + bool __atomic_compare_exchange_strong_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) { + unique_lock _(some_mutex); + if (std::memcmp(const_cast(obj), exp, sizeof(T)) == 0) { + std::memcpy(const_cast(obj), &desr, sizeof(T)); + return true; + } + std::memcpy(exp, const_cast(obj), sizeof(T)); + return false; + } + + template + bool __atomic_compare_exchange_weak_seq_cst_seq_cst(T volatile* obj, T* exp, T desr) { + unique_lock _(some_mutex); + if (std::memcmp(const_cast(obj), exp, sizeof(T)) == 0) + { + std::memcpy(const_cast(obj), &desr, sizeof(T)); + return true; + } + std::memcpy(exp, const_cast(obj), sizeof(T)); + return false; + } + + // T is one of: + // char, signed char, unsigned char, short, unsigned short, + // int, unsigned int, long, unsigned long, + // long long, unsigned long long, char16_t, char32_t, wchar_t + + template + T __atomic_fetch_add_seq_cst(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj += operand; + return r; + } + + template + T __atomic_fetch_sub_seq_cst(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj -= operand; + return r; + } + + template + T __atomic_fetch_and_seq_cst(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj &= operand; + return r; + } + + template + T __atomic_fetch_or_seq_cst(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj |= operand; + return r; + } + + template + T __atomic_fetch_xor_seq_cst(T volatile* obj, T operand) { + unique_lock _(some_mutex); + T r = *obj; + *obj ^= operand; + return r; + } + + void* __atomic_fetch_add_seq_cst(void* volatile* obj, ptrdiff_t operand) { + unique_lock _(some_mutex); + void* r = *obj; + (char*&)(*obj) += operand; + return r; + } + + void* __atomic_fetch_sub_seq_cst(void* volatile* obj, ptrdiff_t operand) { + unique_lock _(some_mutex); + void* r = *obj; + (char*&)(*obj) -= operand; + return r; + } + + void __atomic_thread_fence_seq_cst() { + unique_lock _(some_mutex); + } + + void __atomic_signal_fence_seq_cst() { + unique_lock _(some_mutex); + } + +One should consult the (currently draft) `C++ Standard `_ +for the details of the definitions for these operations. For example, +``__atomic_compare_exchange_weak_seq_cst_seq_cst`` is allowed to fail +spuriously while ``__atomic_compare_exchange_strong_seq_cst_seq_cst`` is not. + +If on your platform the lock-free definition of ``__atomic_compare_exchange_weak_seq_cst_seq_cst`` +would be the same as ``__atomic_compare_exchange_strong_seq_cst_seq_cst``, you may omit the +``__atomic_compare_exchange_weak_seq_cst_seq_cst`` intrinsic without a performance cost. The +library will prefer your implementation of ``__atomic_compare_exchange_strong_seq_cst_seq_cst`` +over its own definition for implementing ``__atomic_compare_exchange_weak_seq_cst_seq_cst``. +That is, the library will arrange for ``__atomic_compare_exchange_weak_seq_cst_seq_cst`` to call +``__atomic_compare_exchange_strong_seq_cst_seq_cst`` if you supply an intrinsic for the strong +version but not the weak. + +Taking advantage of weaker memory synchronization +------------------------------------------------- +So far, all of the intrinsics presented require a **sequentially consistent** memory ordering. +That is, no loads or stores can move across the operation (just as if the library had locked +that internal mutex). But ```` supports weaker memory ordering operations. In all, +there are six memory orderings (listed here from strongest to weakest): + +.. code-block:: cpp + + memory_order_seq_cst + memory_order_acq_rel + memory_order_release + memory_order_acquire + memory_order_consume + memory_order_relaxed + +(See the `C++ Standard `_ for the detailed definitions of each of these orderings). + +On some platforms, the compiler vendor can offer some or even all of the above +intrinsics at one or more weaker levels of memory synchronization. This might +lead for example to not issuing an ``mfence`` instruction on the x86. + +If the compiler does not offer any given operation, at any given memory ordering +level, the library will automatically attempt to call the next highest memory +ordering operation. This continues up to ``seq_cst``, and if that doesn't +exist, then the library takes over and does the job with a ``mutex``. This +is a compile-time search and selection operation. At run time, the application +will only see the few inlined assembly instructions for the selected intrinsic. + +Each intrinsic is appended with the 7-letter name of the memory ordering it +addresses. For example a ``load`` with ``relaxed`` ordering is defined by: + +.. code-block:: cpp + + T __atomic_load_relaxed(const volatile T* obj); + +And announced with: + +.. code-block:: cpp + + __has_feature(__atomic_load_relaxed_b) == 1 // bool + __has_feature(__atomic_load_relaxed_c) == 1 // char + __has_feature(__atomic_load_relaxed_a) == 1 // signed char + ... + +The ``__atomic_compare_exchange_strong(weak)`` intrinsics are parameterized +on two memory orderings. The first ordering applies when the operation returns +``true`` and the second ordering applies when the operation returns ``false``. + +Not every memory ordering is appropriate for every operation. ``exchange`` +and the ``fetch_XXX`` operations support all 6. But ``load`` only supports +``relaxed``, ``consume``, ``acquire`` and ``seq_cst``. ``store`` only supports +``relaxed``, ``release``, and ``seq_cst``. The ``compare_exchange`` operations +support the following 16 combinations out of the possible 36: + +.. code-block:: cpp + + relaxed_relaxed + consume_relaxed + consume_consume + acquire_relaxed + acquire_consume + acquire_acquire + release_relaxed + release_consume + release_acquire + acq_rel_relaxed + acq_rel_consume + acq_rel_acquire + seq_cst_relaxed + seq_cst_consume + seq_cst_acquire + seq_cst_seq_cst + +Again, the compiler supplies intrinsics only for the strongest orderings where +it can make a difference. The library takes care of calling the weakest +supplied intrinsic that is as strong or stronger than the customer asked for. + +Note about ABI +============== +With any design, the (back end) compiler writer should note that the decision to +implement lock-free operations on any given type (or not) is an ABI-binding decision. +One can not change from treating a type as not lock free, to lock free (or vice-versa) +without breaking your ABI. + +For example: + +**TU1.cpp**: + +.. code-block:: cpp + + extern atomic A; + int foo() { return A.compare_exchange_strong(w, x); } + + +**TU2.cpp**: + +.. code-block:: cpp + + extern atomic A; + void bar() { return A.compare_exchange_strong(y, z); } + +If only **one** of these calls to ``compare_exchange_strong`` is implemented with +mutex-locked code, then that mutex-locked code will not be executed mutually +exclusively of the one implemented in a lock-free manner. diff --git a/docs/DesignDocs/AvailabilityMarkup.rst b/docs/DesignDocs/AvailabilityMarkup.rst deleted file mode 100644 index f076dfecd..000000000 --- a/docs/DesignDocs/AvailabilityMarkup.rst +++ /dev/null @@ -1,105 +0,0 @@ -=================== -Availability Markup -=================== - -.. contents:: - :local: - -Overview -======== - -Libc++ is used as a system library on macOS and iOS (amongst others). In order -for users to be able to compile a binary that is intended to be deployed to an -older version of the platform, clang provides the -`availability attribute `_ -that can be placed on declarations to describe the lifecycle of a symbol in the -library. - -Design -====== - -When a new feature is introduced that requires dylib support, a macro should be -created in include/__config to mark this feature as unavailable for all the -systems. For example:: - - // Define availability macros. - #if defined(_LIBCPP_USE_AVAILABILITY_APPLE) - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) - #else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR) - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) - #else - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - #endif - -When the library is updated by the platform vendor, the markup can be updated. -For example:: - - #define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,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))) - -In the source code, the macro can be added on a class if the full class requires -type info from the library for example:: - - _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL - class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access - : public std::logic_error { - -or on a particular symbol: - - _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; - -Furthermore, a lit feature should be added to match that availability macro, -so that tests depending on that feature can be marked to XFAIL if the feature -is not supported. This way, the test suite will work on platforms that have -not shipped the feature yet. This can be done by adding the appropriate lit -feature in test/config.py. - - -Testing -======= - -Some parameters can be passed to lit to run the test-suite and exercise the -availability. - -* The `platform` parameter controls the deployment target. For example lit can - be invoked with `--param=platform=macosx10.8`. Default is the current host. -* The `use_system_cxx_lib` parameter indicates to use another library than the - just built one. Invoking lit with `--param=use_system_cxx_lib=true` will run - the test-suite against the host system library. Alternatively a path to the - directory containing a specific prebuilt libc++ can be used, for example: - `--param=use_system_cxx_lib=/path/to/macOS/10.8/`. - -Tests can be marked as XFAIL based on multiple features made available by lit: - - -* if `--param=platform=macosx10.8` is passed, the following features will be available: - - - availability - - availability=x86_64 - - availability=macosx - - availability=x86_64-macosx - - availability=x86_64-apple-macosx10.8 - - availability=macosx10.8 - - This feature is used to XFAIL a test that *is* using a class or a method marked - as unavailable *and* that is expected to *fail* if deployed on an older system. - -* if `use_system_cxx_lib` and `--param=platform=macosx10.8` are passed to lit, - the following features will also be available: - - - with_system_cxx_lib - - with_system_cxx_lib=x86_64 - - with_system_cxx_lib=macosx - - with_system_cxx_lib=x86_64-macosx - - with_system_cxx_lib=x86_64-apple-macosx10.8 - - with_system_cxx_lib=macosx10.8 - - This feature is used to XFAIL a test that is *not* using a class or a method - marked as unavailable *but* that is expected to fail if deployed on an older - system. For example, if the test exhibits a bug in the libc on a particular - system version, or if the test uses a symbol that is not available on an - older version of the dylib (but for which there is no availability markup, - otherwise the XFAIL should use `availability` above). diff --git a/docs/DesignDocs/CapturingConfigInfo.rst b/docs/DesignDocs/CapturingConfigInfo.rst index 8f2d0cd2d..3ab078e07 100644 --- a/docs/DesignDocs/CapturingConfigInfo.rst +++ b/docs/DesignDocs/CapturingConfigInfo.rst @@ -65,16 +65,12 @@ configuration all together. An example "__config" header generated when #ifndef _LIBCPP_CONFIG_SITE #define _LIBCPP_CONFIG_SITE - /* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */ - /* #undef _LIBCPP_HAS_NO_STDIN */ - /* #undef _LIBCPP_HAS_NO_STDOUT */ #define _LIBCPP_HAS_NO_THREADS /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ - /* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */ #endif // -*- C++ -*- - //===--------------------------- __config ---------------------------------===// + //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/docs/DesignDocs/DebugMode.rst b/docs/DesignDocs/DebugMode.rst index e4d4e5b2d..faf7b8e1b 100644 --- a/docs/DesignDocs/DebugMode.rst +++ b/docs/DesignDocs/DebugMode.rst @@ -7,34 +7,68 @@ Debug Mode .. _using-debug-mode: -Using Debug Mode -================ +Using the debug mode +==================== -Libc++ provides a debug mode that enables assertions meant to detect incorrect -usage of the standard library. By default these assertions are disabled but +Libc++ provides a debug mode that enables special debugging checks meant to detect +incorrect usage of the standard library. These checks are disabled by default, but they can be enabled using the ``_LIBCPP_DEBUG`` macro. -**_LIBCPP_DEBUG** Macro ------------------------ +Note that using the debug mode discussed in this document requires that the library +has been compiled with support for the debug mode (see ``LIBCXX_ENABLE_DEBUG_MODE_SUPPORT``). -**_LIBCPP_DEBUG**: - This macro is used to enable assertions and iterator debugging checks within - libc++. By default it is undefined. +Also note that while the debug mode has no effect on libc++'s ABI, it does have broad ODR +implications. Users should compile their whole program at the same debugging level. - **Values**: ``0``, ``1`` +The various levels of checking provided by the debug mode follow. - Defining ``_LIBCPP_DEBUG`` to ``0`` or greater enables most of libc++'s - assertions. Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging" - which provides additional assertions about the validity of iterators used by - the program. +No debugging checks (``_LIBCPP_DEBUG`` not defined) +--------------------------------------------------- +When ``_LIBCPP_DEBUG`` is not defined, there are no debugging checks performed by +the library. This is the default. - Note that this option has no effect on libc++'s ABI; but it does have broad - ODR implications. Users should compile their whole program at the same - debugging level. +Basic checks (``_LIBCPP_DEBUG == 0``) +------------------------------------- +When ``_LIBCPP_DEBUG`` is defined to ``0`` (to be understood as level ``0``), some +debugging checks are enabled. The non-exhaustive list of things is: + +- Many algorithms, such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``, + wrap the user-provided comparator to assert that `!comp(y, x)` whenever + `comp(x, y)`. This can cause the user-provided comparator to be evaluated + up to twice as many times as it would be without ``_LIBCPP_DEBUG``, and + causes the library to violate some of the Standard's complexity clauses. + +- FIXME: Update this list + +Iterator debugging checks (``_LIBCPP_DEBUG == 1``) +-------------------------------------------------- +Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging", which provides +additional assertions about the validity of iterators used by the program. + +The following containers and classes support iterator debugging: + +- ``std::string`` +- ``std::vector`` (``T != bool``) +- ``std::list`` +- ``std::unordered_map`` +- ``std::unordered_multimap`` +- ``std::unordered_set`` +- ``std::unordered_multiset`` + +The remaining containers do not currently support iterator debugging. +Patches welcome. + +Randomizing Unspecified Behavior (``_LIBCPP_DEBUG == 1``) +--------------------------------------------------------- +This also enables the randomization of unspecified behavior, for +example, for equal elements in ``std::sort`` or randomizing both parts of +the partition after ``std::nth_element`` call. This effort helps you to migrate +to potential future faster versions of these algorithms and deflake your tests +which depend on such behavior. To fix the seed, use +``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed`` definition. Handling Assertion Failures ---------------------------- - +=========================== When a debug assertion fails the assertion handler is called via the ``std::__libcpp_debug_function`` function pointer. It is possible to override this function pointer using a different handler function. Libc++ provides a @@ -55,37 +89,3 @@ assertion handler as follows. str.insert(bad_it, '!'); // causes debug assertion // control flow doesn't return } - -Debug Mode Checks -================= - -Libc++'s debug mode offers two levels of checking. The first enables various -precondition checks throughout libc++. The second additionally enables -"iterator debugging" which checks the validity of iterators used by the program. - -Basic Checks -============ - -These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1. - -The following checks are enabled by ``_LIBCPP_DEBUG``: - - * FIXME: Update this list - -Iterator Debugging Checks -========================= - -These checks are enabled when ``_LIBCPP_DEBUG`` is defined to 1. - -The following containers and STL classes support iterator debugging: - - * ``std::string`` - * ``std::vector`` (``T != bool``) - * ``std::list`` - * ``std::unordered_map`` - * ``std::unordered_multimap`` - * ``std::unordered_set`` - * ``std::unordered_multiset`` - -The remaining containers do not currently support iterator debugging. -Patches welcome. diff --git a/docs/DesignDocs/FeatureTestMacros.rst b/docs/DesignDocs/FeatureTestMacros.rst index 2fbba6547..2c6f983ee 100644 --- a/docs/DesignDocs/FeatureTestMacros.rst +++ b/docs/DesignDocs/FeatureTestMacros.rst @@ -8,7 +8,7 @@ Feature Test Macros Overview ======== -Libc++ implements the C++ feature test macros as specified in the C++2a standard, +Libc++ implements the C++ feature test macros as specified in the C++20 standard, and before that in non-normative guiding documents (`See cppreference `_) @@ -39,7 +39,5 @@ The `generate_feature_test_macro_components.py` script is used to track and update feature test macros in libc++. Whenever a feature test macro is added or changed, the table should be updated -and the script should be re-ran. The script will clobber the existing test files -and the documentation and it will generate a new `` header as a -temporary file. The generated `` header should be merged with the -existing one. +and the script should be re-ran. The script will clobber the existing test files, +the documentation and the `` header. diff --git a/docs/DesignDocs/FileTimeType.rst b/docs/DesignDocs/FileTimeType.rst index f1e9edd87..a54d2bf27 100644 --- a/docs/DesignDocs/FileTimeType.rst +++ b/docs/DesignDocs/FileTimeType.rst @@ -18,7 +18,7 @@ type, which is a specialization of ``chrono::time_point`` for the trivial-clock is an implementation-defined type that satisfies the Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of representing and measuring file time values. Implementations should ensure - that the resolution and range of file_­time_­type reflect the operating + that the resolution and range of file_time_type reflect the operating system dependent resolution and range of file time values. diff --git a/docs/DesignDocs/NoexceptPolicy.rst b/docs/DesignDocs/NoexceptPolicy.rst new file mode 100644 index 000000000..8dc5e14e4 --- /dev/null +++ b/docs/DesignDocs/NoexceptPolicy.rst @@ -0,0 +1,13 @@ +==================== +``noexcept`` Policy +==================== + +Extended applications of ``noexcept`` +------------------------------------------ + +As of version 13 libc++ may mark functions that do not throw (i.e., +"Throws: Nothing") as ``noexcept``. This has two primary consequences: +first, functions might not report precondition violations by throwing. +Second, user-provided functions, such as custom predicates or custom +traits, which throw might not be propagated up to the caller (unless +specified otherwise by the Standard). diff --git a/docs/DesignDocs/UniquePtrTrivialAbi.rst b/docs/DesignDocs/UniquePtrTrivialAbi.rst new file mode 100644 index 000000000..1af0b3426 --- /dev/null +++ b/docs/DesignDocs/UniquePtrTrivialAbi.rst @@ -0,0 +1,149 @@ +============================================= +Enable std::unique_ptr [[clang::trivial_abi]] +============================================= + +Background +========== + +Consider the follow snippets + + +.. code-block:: cpp + + void raw_func(Foo* raw_arg) { ... } + void smart_func(std::unique_ptr smart_arg) { ... } + + Foo* raw_ptr_retval() { ... } + std::unique_ptr smart_ptr_retval() { ... } + + + +The argument ``raw_arg`` could be passed in a register but ``smart_arg`` could not, due to current +implementation. + +Specifically, in the ``smart_arg`` case, the caller secretly constructs a temporary ``std::unique_ptr`` +in its stack-frame, and then passes a pointer to it to the callee in a hidden parameter. +Similarly, the return value from ``smart_ptr_retval`` is secretly allocated in the caller and +passed as a secret reference to the callee. + + +Goal +=================== + +``std::unique_ptr`` is passed directly in a register. + +Design +====== + +* Annotate the two definitions of ``std::unique_ptr`` with ``clang::trivial_abi`` attribute. +* Put the attribute behind a flag because this change has potential compilation and runtime breakages. + + +This comes with some side effects: + +* ``std::unique_ptr`` parameters will now be destroyed by callees, rather than callers. + It is worth noting that destruction by callee is not unique to the use of trivial_abi attribute. + In most Microsoft's ABIs, arguments are always destroyed by the callee. + + Consequently, this may change the destruction order for function parameters to an order that is non-conforming to the standard. + For example: + + + .. code-block:: cpp + + struct A { ~A(); }; + struct B { ~B(); }; + struct C { C(A, unique_ptr, A) {} }; + C c{{}, make_unique, {}}; + + + In a conforming implementation, the destruction order for C::C's parameters is required to be ``~A(), ~B(), ~A()`` but with this mode enabled, we'll instead see ``~B(), ~A(), ~A()``. + +* Reduced code-size. + + +Performance impact +------------------ + +Google has measured performance improvements of up to 1.6% on some large server macrobenchmarks, and a small reduction in binary sizes. + +This also affects null pointer optimization + +Clang's optimizer can now figure out when a `std::unique_ptr` is known to contain *non*-null. +(Actually, this has been a *missed* optimization all along.) + + +.. code-block:: cpp + + struct Foo { + ~Foo(); + }; + std::unique_ptr make_foo(); + void do_nothing(const Foo&) + + void bar() { + auto x = make_foo(); + do_nothing(*x); + } + + +With this change, ``~Foo()`` will be called even if ``make_foo`` returns ``unique_ptr(nullptr)``. +The compiler can now assume that ``x.get()`` cannot be null by the end of ``bar()``, because +the deference of ``x`` would be UB if it were ``nullptr``. (This dereference would not have caused +a segfault, because no load is generated for dereferencing a pointer to a reference. This can be detected with ``-fsanitize=null``). + + +Potential breakages +------------------- + +The following breakages were discovered by enabling this change and fixing the resulting issues in a large code base. + +- Compilation failures + + - Function definitions now require complete type ``T`` for parameters with type ``std::unique_ptr``. The following code will no longer compile. + + .. code-block:: cpp + + class Foo; + void func(std::unique_ptr arg) { /* never use `arg` directly */ } + + - Fix: Remove forward-declaration of ``Foo`` and include its proper header. + +- Runtime Failures + + - Lifetime of ``std::unique_ptr<>`` arguments end earlier (at the end of the callee's body, rather than at the end of the full expression containing the call). + + .. code-block:: cpp + + util::Status run_worker(std::unique_ptr); + void func() { + std::unique_ptr smart_foo = ...; + Foo* owned_foo = smart_foo.get(); + // Currently, the following would "work" because the argument to run_worker() is deleted at the end of func() + // With the new calling convention, it will be deleted at the end of run_worker(), + // making this an access to freed memory. + owned_foo->Bar(run_worker(std::move(smart_foo))); + ^ + // <<`` ends earlier. + + Spot the bug: + + .. code-block:: cpp + + std::unique_ptr create_and_subscribe(Bar* subscriber) { + auto foo = std::make_unique(); + subscriber->sub([&foo] { foo->do_thing();} ); + return foo; + } + + One could point out this is an obvious stack-use-after return bug. + With the current calling convention, running this code with ASAN enabled, however, would not yield any "issue". + So is this a bug in ASAN? (Spoiler: No) + + This currently would "work" only because the storage for ``foo`` is in the caller's stackframe. + In other words, ``&foo`` in callee and ``&foo`` in the caller are the same address. + +ASAN can be used to detect both of these. diff --git a/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst b/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst new file mode 100644 index 000000000..783950b3b --- /dev/null +++ b/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst @@ -0,0 +1,86 @@ +================================== +Unspecified Behavior Randomization +================================== + +Background +========== + +Consider the follow snippet which steadily happens in tests: + + +.. code-block:: cpp + + std::vector> v(SomeData()); + std::sort(v.begin(), v.end(), [](const auto& lhs, const auto& rhs) { + return lhs.first < rhs.first; + }); + +Under this assumption all elements in the vector whose first elements are equal +do not guarantee any order. Unfortunately, this prevents libcxx introducing +other implementatiosn because tests might silently fail and the users might +heavily depend on the stability of implementations. + +Goal +=================== + +Provide functionality for randomizing the unspecified behavior so that the users +can test and migrate their components and libcxx can introduce new sorting +algorithms and optimizations to the containers. + +For example, as of LLVM version 13, libcxx sorting algorithm takes +`O(n^2) worst case `_ but according +to the standard its worst case should be `O(n log n)`. This effort helps users +to gradually fix their tests while updating to new faster algorithms. + +Design +====== + +* Introduce new macro `_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY` which should + be a part of the libcxx config. +* This macro randomizes the unspecified behavior of algorithms and containers. + For example, for sorting algorithm the input range is shuffled and then + sorted. +* This macro is off by default because users should enable it only for testing + purposes and/or migrations if they happen to libcxx. +* This feature is only available for C++11 and further because of + `std::shuffle` availability. +* We may use `ASLR `_ or + static `std::random_device` for seeding the random number generator. This + guarantees the same stability guarantee within a run but not through different + runs, for example, for tests become flaky and eventually be seen as broken. + For platforms which do not support ASLR, the seed is fixed during build. +* The users can fix the seed of the random number generator by providing + `_LIBCPP_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed` definition. + +This comes with some side effects if any of the flags is on: + +* Computation penalty, we think users are OK with that if they use this feature. +* Non reproducible results if they don't use the fixed seed. + + +Impact +------------------ + +Google has measured couple of thousands of tests to be dependent on the +stability of sorting and selection algorithms. As we also plan on updating +(or least, providing under flag more) sorting algorithms, this effort helps +doing it gradually and sustainably. This is also bad for users to depend on the +unspecified behavior in their tests, this effort helps to turn this flag in +debug mode. + +Potential breakages +------------------- + +None if the flag is off. If the flag is on, it may lead to some non-reproducible +results, for example, for caching. + +Currently supported randomization +--------------------------------- + +* `std::sort`, there is no guarantee on the order of equal elements +* `std::partial_sort`, there is no guarantee on the order of equal elements and + on the order of the remaining part +* `std::nth_element`, there is no guarantee on the order from both sides of the + partition + +Patches welcome. diff --git a/docs/DesignDocs/VisibilityMacros.rst b/docs/DesignDocs/VisibilityMacros.rst index d0d4f0adb..e5aa50097 100644 --- a/docs/DesignDocs/VisibilityMacros.rst +++ b/docs/DesignDocs/VisibilityMacros.rst @@ -5,6 +5,8 @@ Symbol Visibility Macros .. contents:: :local: +.. _visibility-macros: + Overview ======== @@ -44,6 +46,10 @@ Visibility Macros Mark a function as not being part of the ABI of any final linked image that uses it. +**_LIBCPP_INLINE_VISIBILITY** + Historical predecessor of ``_LIBCPP_HIDE_FROM_ABI`` -- please use + ``_LIBCPP_HIDE_FROM_ABI`` instead. + **_LIBCPP_HIDE_FROM_ABI_AFTER_V1** Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`) when libc++ is built with an ABI version after ABI v1. This macro is used to @@ -131,12 +137,6 @@ Visibility Macros specified on the primary template and to export the member functions produced by the explicit instantiation in the dylib. - **GCC Behavior**: GCC ignores visibility attributes applied the type in - extern template declarations and applying an attribute results in a warning. - However since `_LIBCPP_TEMPLATE_VIS` is the same as - `__attribute__((visibility("default"))` the visibility is already correct. - The macro has an empty definition with GCC. - **Windows Behavior**: `extern template` and `dllexport` are fundamentally incompatible *on a class template* on Windows; the former suppresses instantiation, while the latter forces it. Specifying both on the same diff --git a/docs/FeatureTestMacroTable.rst b/docs/FeatureTestMacroTable.rst index 2200a998a..3cfcaa662 100644 --- a/docs/FeatureTestMacroTable.rst +++ b/docs/FeatureTestMacroTable.rst @@ -18,185 +18,318 @@ Status ====== .. table:: Current Status - :name: feature-status-table - :widths: auto - + :name: feature-status-table + :widths: auto + ================================================= ================= - Macro Name Value + Macro Name Value ================================================= ================= - **C++ 14** + **C++ 14** ------------------------------------------------------------------- - ``__cpp_lib_chrono_udls`` ``201304L`` + ``__cpp_lib_chrono_udls`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_complex_udls`` ``201309L`` + ``__cpp_lib_complex_udls`` ``201309L`` ------------------------------------------------- ----------------- - ``__cpp_lib_exchange_function`` ``201304L`` + ``__cpp_lib_exchange_function`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_generic_associative_lookup`` ``201304L`` + ``__cpp_lib_generic_associative_lookup`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_integer_sequence`` ``201304L`` + ``__cpp_lib_integer_sequence`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_integral_constant_callable`` ``201304L`` + ``__cpp_lib_integral_constant_callable`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_final`` ``201402L`` + ``__cpp_lib_is_final`` ``201402L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_null_pointer`` ``201309L`` + ``__cpp_lib_is_null_pointer`` ``201309L`` ------------------------------------------------- ----------------- - ``__cpp_lib_make_reverse_iterator`` ``201402L`` + ``__cpp_lib_make_reverse_iterator`` ``201402L`` ------------------------------------------------- ----------------- - ``__cpp_lib_make_unique`` ``201304L`` + ``__cpp_lib_make_unique`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_null_iterators`` ``201304L`` + ``__cpp_lib_null_iterators`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_quoted_string_io`` ``201304L`` + ``__cpp_lib_quoted_string_io`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_result_of_sfinae`` ``201210L`` + ``__cpp_lib_result_of_sfinae`` ``201210L`` ------------------------------------------------- ----------------- - ``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L`` + ``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_shared_timed_mutex`` ``201402L`` + ``__cpp_lib_shared_timed_mutex`` ``201402L`` ------------------------------------------------- ----------------- - ``__cpp_lib_string_udls`` ``201304L`` + ``__cpp_lib_string_udls`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_transformation_trait_aliases`` ``201304L`` + ``__cpp_lib_transformation_trait_aliases`` ``201304L`` ------------------------------------------------- ----------------- - ``__cpp_lib_transparent_operators`` ``201210L`` + ``__cpp_lib_transparent_operators`` ``201210L`` ------------------------------------------------- ----------------- - ``__cpp_lib_tuple_element_t`` ``201402L`` + ``__cpp_lib_tuple_element_t`` ``201402L`` ------------------------------------------------- ----------------- - ``__cpp_lib_tuples_by_type`` ``201304L`` + ``__cpp_lib_tuples_by_type`` ``201304L`` ------------------------------------------------- ----------------- - **C++ 17** + **C++ 17** ------------------------------------------------------------------- - ``__cpp_lib_addressof_constexpr`` ``201603L`` + ``__cpp_lib_addressof_constexpr`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_allocator_traits_is_always_equal`` ``201411L`` + ``__cpp_lib_allocator_traits_is_always_equal`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_any`` ``201606L`` + ``__cpp_lib_any`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_apply`` ``201603L`` + ``__cpp_lib_apply`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_array_constexpr`` ``201603L`` + ``__cpp_lib_array_constexpr`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_as_const`` ``201510L`` + ``__cpp_lib_as_const`` ``201510L`` ------------------------------------------------- ----------------- - ``__cpp_lib_atomic_is_always_lock_free`` ``201603L`` + ``__cpp_lib_atomic_is_always_lock_free`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_bool_constant`` ``201505L`` + ``__cpp_lib_bool_constant`` ``201505L`` ------------------------------------------------- ----------------- - ``__cpp_lib_boyer_moore_searcher`` *unimplemented* + ``__cpp_lib_boyer_moore_searcher`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_byte`` ``201603L`` + ``__cpp_lib_byte`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_chrono`` ``201611L`` + ``__cpp_lib_chrono`` ``201611L`` ------------------------------------------------- ----------------- - ``__cpp_lib_clamp`` ``201603L`` + ``__cpp_lib_clamp`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_enable_shared_from_this`` ``201603L`` + ``__cpp_lib_enable_shared_from_this`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_execution`` *unimplemented* + ``__cpp_lib_execution`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_filesystem`` ``201703L`` + ``__cpp_lib_filesystem`` ``201703L`` ------------------------------------------------- ----------------- - ``__cpp_lib_gcd_lcm`` ``201606L`` + ``__cpp_lib_gcd_lcm`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_hardware_interference_size`` ``201703L`` + ``__cpp_lib_hardware_interference_size`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_has_unique_object_representations`` ``201606L`` + ``__cpp_lib_has_unique_object_representations`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_hypot`` ``201603L`` + ``__cpp_lib_hypot`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_incomplete_container_elements`` ``201505L`` + ``__cpp_lib_incomplete_container_elements`` ``201505L`` ------------------------------------------------- ----------------- - ``__cpp_lib_invoke`` ``201411L`` + ``__cpp_lib_invoke`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_aggregate`` ``201703L`` + ``__cpp_lib_is_aggregate`` ``201703L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_invocable`` ``201703L`` + ``__cpp_lib_is_invocable`` ``201703L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_swappable`` ``201603L`` + ``__cpp_lib_is_swappable`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_launder`` ``201606L`` + ``__cpp_lib_launder`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_logical_traits`` ``201510L`` + ``__cpp_lib_logical_traits`` ``201510L`` ------------------------------------------------- ----------------- - ``__cpp_lib_make_from_tuple`` ``201606L`` + ``__cpp_lib_make_from_tuple`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_map_try_emplace`` ``201411L`` + ``__cpp_lib_map_try_emplace`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_math_special_functions`` *unimplemented* + ``__cpp_lib_math_special_functions`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_memory_resource`` *unimplemented* + ``__cpp_lib_memory_resource`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_node_extract`` ``201606L`` + ``__cpp_lib_node_extract`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_nonmember_container_access`` ``201411L`` + ``__cpp_lib_nonmember_container_access`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_not_fn`` ``201603L`` + ``__cpp_lib_not_fn`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_optional`` ``201606L`` + ``__cpp_lib_optional`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_parallel_algorithm`` *unimplemented* + ``__cpp_lib_parallel_algorithm`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_raw_memory_algorithms`` ``201606L`` + ``__cpp_lib_raw_memory_algorithms`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_sample`` ``201603L`` + ``__cpp_lib_sample`` ``201603L`` ------------------------------------------------- ----------------- - ``__cpp_lib_scoped_lock`` ``201703L`` + ``__cpp_lib_scoped_lock`` ``201703L`` ------------------------------------------------- ----------------- - ``__cpp_lib_shared_mutex`` ``201505L`` + ``__cpp_lib_shared_mutex`` ``201505L`` ------------------------------------------------- ----------------- - ``__cpp_lib_shared_ptr_arrays`` *unimplemented* + ``__cpp_lib_shared_ptr_arrays`` ``201611L`` ------------------------------------------------- ----------------- - ``__cpp_lib_shared_ptr_weak_type`` ``201606L`` + ``__cpp_lib_shared_ptr_weak_type`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_string_view`` ``201606L`` + ``__cpp_lib_string_view`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_to_chars`` *unimplemented* + ``__cpp_lib_to_chars`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_transparent_operators`` ``201510L`` + ``__cpp_lib_transparent_operators`` ``201510L`` ------------------------------------------------- ----------------- - ``__cpp_lib_type_trait_variable_templates`` ``201510L`` + ``__cpp_lib_type_trait_variable_templates`` ``201510L`` ------------------------------------------------- ----------------- - ``__cpp_lib_uncaught_exceptions`` ``201411L`` + ``__cpp_lib_uncaught_exceptions`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_unordered_map_try_emplace`` ``201411L`` + ``__cpp_lib_unordered_map_try_emplace`` ``201411L`` ------------------------------------------------- ----------------- - ``__cpp_lib_variant`` ``201606L`` + ``__cpp_lib_variant`` ``202102L`` ------------------------------------------------- ----------------- - ``__cpp_lib_void_t`` ``201411L`` + ``__cpp_lib_void_t`` ``201411L`` ------------------------------------------------- ----------------- - **C++ 2a** + **C++ 20** ------------------------------------------------------------------- - ``__cpp_lib_atomic_ref`` *unimplemented* + ``__cpp_lib_array_constexpr`` ``201811L`` ------------------------------------------------- ----------------- - ``__cpp_lib_bind_front`` *unimplemented* + ``__cpp_lib_assume_aligned`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_bit_cast`` *unimplemented* + ``__cpp_lib_atomic_flag_test`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_char8_t`` ``201811L`` + ``__cpp_lib_atomic_float`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_concepts`` *unimplemented* + ``__cpp_lib_atomic_lock_free_type_aliases`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_misc`` *unimplemented* + ``__cpp_lib_atomic_ref`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_swap_algorithms`` *unimplemented* + ``__cpp_lib_atomic_shared_ptr`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_destroying_delete`` ``201806L`` + ``__cpp_lib_atomic_value_initialization`` ``201911L`` ------------------------------------------------- ----------------- - ``__cpp_lib_erase_if`` ``201811L`` + ``__cpp_lib_atomic_wait`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_generic_unordered_lookup`` *unimplemented* + ``__cpp_lib_barrier`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_interpolate`` ``201902L`` + ``__cpp_lib_bind_front`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_is_constant_evaluated`` ``201811L`` + ``__cpp_lib_bit_cast`` ``201806L`` ------------------------------------------------- ----------------- - ``__cpp_lib_list_remove_return_type`` *unimplemented* + ``__cpp_lib_bitops`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_ranges`` *unimplemented* + ``__cpp_lib_bounded_array_traits`` ``201902L`` ------------------------------------------------- ----------------- - ``__cpp_lib_three_way_comparison`` *unimplemented* + ``__cpp_lib_char8_t`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_concepts`` ``202002L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_algorithms`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_complex`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_dynamic_alloc`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_functional`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_iterator`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_memory`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_numeric`` ``201911L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_string`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_string_view`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_tuple`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_utility`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_vector`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_coroutine`` ``201902L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_destroying_delete`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_endian`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_erase_if`` ``202002L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_execution`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_format`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_generic_unordered_lookup`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_int_pow2`` ``202002L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_integer_comparison_functions`` ``202002L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_interpolate`` ``201902L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_is_constant_evaluated`` ``201811L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_is_layout_compatible`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_is_nothrow_convertible`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_is_pointer_interconvertible`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_jthread`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_latch`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_list_remove_return_type`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_math_constants`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_polymorphic_allocator`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_remove_cvref`` ``201711L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_semaphore`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_shift`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_smart_ptr_for_overwrite`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_source_location`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_span`` ``202002L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_ssize`` ``201902L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_starts_ends_with`` ``201711L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_string_view`` ``201803L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_syncbuf`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_three_way_comparison`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_to_address`` ``201711L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_to_array`` ``201907L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_type_identity`` ``201806L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_unwrap_ref`` ``201811L`` + ------------------------------------------------- ----------------- + **C++ 2b** + ------------------------------------------------------------------- + ``__cpp_lib_adaptor_iterator_pair_constructor`` ``202106L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_allocate_at_least`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_associative_heterogeneous_erasure`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_byteswap`` ``202110L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_typeinfo`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_invoke_r`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_is_scoped_enum`` ``202011L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_monadic_optional`` ``202110L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_move_only_function`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_out_ptr`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_starts_ends_with`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_zip`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_spanstream`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_stacktrace`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_stdatomic_h`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_string_contains`` ``202011L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_string_resize_and_overwrite`` ``202110L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_to_underlying`` ``202102L`` ================================================= ================= - diff --git a/docs/Helpers/Styles.rst b/docs/Helpers/Styles.rst new file mode 100644 index 000000000..6291d4df7 --- /dev/null +++ b/docs/Helpers/Styles.rst @@ -0,0 +1,51 @@ +.. raw:: html + + + +.. role:: notstarted +.. role:: nothingtodo +.. role:: inprogress +.. role:: inreview +.. role:: partial +.. role:: complete + +.. |Not Started| replace:: :notstarted:`Not Started` +.. |Nothing To Do| replace:: :nothingtodo:`Nothing To Do` +.. |In Progress| replace:: :inprogress:`In Progress` +.. |Review| replace:: :inreview:`Review` +.. |Partial| replace:: :partial:`Partial` +.. |Complete| replace:: :complete:`Complete` + +.. role:: chrono +.. role:: format +.. role:: ranges +.. role:: spaceship + +.. |chrono| replace:: :chrono:`chrono` +.. |format| replace:: :format:`format` +.. |ranges| replace:: :ranges:`ranges` +.. |spaceship| replace:: :spaceship:`spaceship` + +.. |sect| unicode:: U+00A7 +.. |hellip| unicode:: U+2026 diff --git a/docs/Makefile.sphinx b/docs/Makefile.sphinx deleted file mode 100644 index a34f0cc0b..000000000 --- a/docs/Makefile.sphinx +++ /dev/null @@ -1,37 +0,0 @@ -# Makefile for Sphinx documentation -# -# FIXME: This hack is only in place to allow the libcxx.llvm.org/docs builder -# to work with libcxx. This should be removed when that builder supports -# out-of-tree builds. - -# You can set these variables from the command line. -SPHINXOPTS = -n -W -v -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext default - -default: html - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @# FIXME: Remove this `cp` once HTML->Sphinx transition is completed. - @# Kind of a hack, but HTML-formatted docs are on the way out anyway. - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - diff --git a/docs/README.txt b/docs/README.txt index 06d94f5b5..ff7e71f10 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -11,3 +11,7 @@ To build the documents into html configure libc++ with the following cmake optio After configuring libc++ with these options the make rule `docs-libcxx-html` should be available. + +The documentation in this directory is published at https://libcxx.llvm.org. It is kept up-to-date +by a build bot: https://lab.llvm.org/buildbot/#/builders/publish-sphinx-docs. If you notice that the +documentation is not updating anymore, please contact one of the maintainers. diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index f1dd6f989..20303382d 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,5 +1,5 @@ ========================================= -Libc++ 10.0.0 (In-Progress) Release Notes +Libc++ 14.0.0 (In-Progress) Release Notes ========================================= .. contents:: @@ -10,7 +10,7 @@ Written by the `Libc++ Team `_ .. warning:: - These are in-progress notes for the upcoming libc++ 10 release. + These are in-progress notes for the upcoming libc++ 14 release. Release notes for previous releases can be found on `the Download Page `_. @@ -18,7 +18,7 @@ Introduction ============ This document contains the release notes for the libc++ C++ Standard Library, -part of the LLVM Compiler Infrastructure, release 10.0.0. Here we describe the +part of the LLVM Compiler Infrastructure, release 14.0.0. Here we describe the status of libc++ in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM documentation `_. All LLVM releases may @@ -27,17 +27,219 @@ be downloaded from the `LLVM releases web site `_. For more information about libc++, please see the `Libc++ Web Site `_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the +Note that if you are reading this file from a Git checkout or the main Libc++ web page, this document applies to the *next* release, not the current one. To see the release notes for a specific release, please see the `releases page `_. -What's New in Libc++ 10.0.0? +What's New in Libc++ 14.0.0? ============================ New Features ------------ +- There's support for the C++20 header ````. Some parts are still + missing, most notably the compile-time format string validation. Some + functions are known to be inefficient, both in memory usage and performance. + The implementation isn't API- or ABI-stable and therefore considered + experimental. (Some not-yet-implemented papers require an API-break.) + As a result, it is disabled by default, however vendors can enable the + header by using ``-DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON`` when + configuring their build. + +- More parts of ```` have been implemented. Since we still expect to make + some API and ABI breaking changes, those are disabled by default. However, + vendors that wish to enable ```` in their distribution may do so + by defining ``-DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON`` when configuring + their build. + +- There's a new CMake option ``LIBCXX_ENABLE_UNICODE`` to disable Unicode + support in the ```` header. This only affects the estimation of the + output width of the format functions. + +- Support for building libc++ on top of a C Standard Library that does not support ``wchar_t`` was + added. This is useful for building libc++ in an embedded setting, and it adds itself to the various + freestanding-friendly options provided by libc++. + +- Defining ``_LIBCPP_DEBUG`` to ``1`` enables the randomization of unspecified + behavior in standard algorithms (e.g. the ordering of equal elements in ``std::sort``, or + the ordering of both sides of the partition in ``std::nth_element``). + +- Floating-point support for ``std::to_chars`` support has been added. + Thanks to Stephan T. Lavavej and Microsoft for providing their implementation + to libc++. + +- The C++20 ```` implementation has been completed. + +- More C++20 features have been implemented. :doc:`Status/Cxx20` has the full + overview of libc++'s C++20 implementation status. + +- More C++2b features have been implemented. :doc:`Status/Cxx2b` has the full + overview of libc++'s C++2b implementation status. + +- 16-bit ``wchar_t`` handling added for ``codecvt_utf8``, ``codecvt_utf16`` and + ``codecvt_utf8_utf16``. + API Changes ----------- -- ... + +- The functions ``std::atomic::fetch_(add|sub)`` and + ``std::atomic_fetch_(add|sub)`` no longer accept a function pointer. While + this is technically an API break, the invalid syntax isn't supported by + libstdc++ and MSVC STL. See https://godbolt.org/z/49fvzz98d. + +- The call of the functions ``std::atomic_(add|sub)(std::atomic*, ...)`` + with the explicit template argument ``T`` are now ill-formed. While this is + technically an API break, the invalid syntax isn't supported by libstdc++ and + MSVC STL. See https://godbolt.org/z/v9959re3v. + + Due to this change it's now possible to call these functions with the + explicit template argument ``T*``. This allows using the same syntax on the + major Standard library implementations. + See https://godbolt.org/z/oEfzPhTTb. + + Calls to these functions where the template argument was deduced by the + compiler are unaffected by this change. + +- The functions ``std::allocator::allocate`` and + ``std::experimental::pmr::polymorphic_allocator::allocate`` now throw + an exception of type ``std::bad_array_new_length`` when the requested size + exceeds the maximum supported size, as required by the C++ standard. + Previously the type ``std::length_error`` was used. + +- Removed the nonstandard methods ``std::chrono::file_clock::to_time_t`` and + ``std::chrono::file_clock::from_time_t``; neither libstdc++ nor MSVC STL + had such methods. Instead, in C++20, you can use ``std::chrono::file_clock::from_sys`` + and ``std::chrono::file_clock::to_sys``, which are specified in the Standard. + If you are not using C++20, you should move to it. + +- The declarations of functions ``declare_reachable``, ``undeclare_reachable``, ``declare_no_pointers``, + ``undeclare_no_pointers``, and ``get_pointer_safety`` have been removed not only from C++2b but + from all modes. Their symbols are still provided by the dynamic library for the benefit of + existing compiled code. All of these functions have always behaved as no-ops. + +- ``std::filesystem::path::iterator``, which (in our implementation) stashes + a ``path`` value inside itself similar to ``istream_iterator``, now sets its + ``reference`` type to ``path`` and its ``iterator_category`` to ``input_iterator_tag``, + so that it is a conforming input iterator in C++17 and a conforming + ``std::bidirectional_iterator`` in C++20. Before this release, it had set its + ``reference`` type to ``const path&`` and its ``iterator_category`` to + ``bidirectional_iterator_tag``, making it a non-conforming bidirectional iterator. + After this change, ``for`` loops of the form ``for (auto& c : path)`` must be rewritten + as either ``for (auto&& c : path)`` or ``for (const auto& c : path)``. + ``std::reverse_iterator`` is no longer rejected. + +- Removed the nonstandard default constructor from ``std::chrono::month_weekday``. + You must now explicitly initialize with a ``chrono::month`` and + ``chrono::weekday_indexed`` instead of "meh, whenever". + +- C++20 requires that ``std::basic_string::reserve(n)`` never reduce the capacity + of the string. (For that, use ``shrink_to_fit()``.) Prior to this release, libc++'s + ``std::basic_string::reserve(n)`` could reduce capacity in C++17 and before, but + not in C++20 and later. This caused ODR violations when mixing code compiled under + different Standard modes. After this change, libc++'s ``std::basic_string::reserve(n)`` + never reduces capacity, even in C++17 and before. + C++20 deprecates the zero-argument overload of ``std::basic_string::reserve()``, + but specifically permits it to reduce capacity. To avoid breaking existing code + assuming that ``std::basic_string::reserve()`` will shrink, libc++ maintains + the behavior to shrink, even though that makes ``std::basic_string::reserve()`` not + a synonym for ``std::basic_string::reserve(0)`` in any Standard mode anymore. + +- The ```` header is deprecated, as is any + use of coroutines without C++20. Use C++20's ```` header + instead. The ```` header will be removed + in LLVM 16. + +- ``_VSTD`` is now an alias for ``std`` instead of ``std::_LIBCPP_ABI_NAMESPACE``. + This is technically not a functional change, except for folks that might have been + using ``_VSTD`` in creative ways (which has never been officially supported). + +ABI Changes +----------- + +- The C++17 variable templates ``is_error_code_enum_v`` and + ``is_error_condition_enum_v`` are now of type ``bool`` instead of ``size_t``. + +- The C++03 emulation type for ``std::nullptr_t`` has been removed in favor of + using ``decltype(nullptr)`` in all standard modes. This is an ABI break for + anyone compiling in C++03 mode and who has ``std::nullptr_t`` as part of their + ABI. However, previously, these users' ABI would be incompatible with any other + binary or static archive compiled with C++11 or later. If you start seeing linker + errors involving ``std::nullptr_t`` against previously compiled binaries, this may + be the cause. You can define the ``_LIBCPP_ABI_USE_CXX03_NULLPTR_EMULATION`` macro + to return to the previous behavior. That macro will be removed in LLVM 15. Please + comment `on D109459 `_ if you are broken by this change + and need to define the macro. + +- On Apple platforms, ``std::random_device`` is now implemented on top of ``arc4random()`` + instead of reading from ``/dev/urandom``. Any implementation-defined token used when + constructing a ``std::random_device`` will now be ignored instead of interpreted as a + file to read entropy from. + +- ``std::lognormal_distribution::param_type`` used to store a data member of type + ``std::normal_distribution``; now this member is stored in the ``lognormal_distribution`` + class itself, and the ``param_type`` stores only the mean and standard deviation, + as required by the Standard. This changes ``sizeof(std::lognormal_distribution::param_type)``. + You can define the ``_LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION`` macro to return to the + previous behavior. That macro will be removed in LLVM 15. Please comment + `on PR52906 `_ if you are broken by this change and need to + define the macro. + +Build System Changes +-------------------- + +- Building the libc++ shared or static library requires a C++ 20 capable compiler. + Consider using a Bootstrapping build to build libc++ with a fresh Clang if you + can't use the system compiler to build libc++ anymore. + +- Historically, there have been numerous ways of building libc++, libc++abi, and libunwind. + This has led to at least 5 different ways to build the runtimes, which was impossible to + maintain with a good level of support. Starting with this release, libc++, libc++abi, and + libunwind support exactly two ways of being built, which should cater to all use-cases. + Furthermore, these builds are as lightweight as possible and will work consistently even + when targeting embedded platforms, which used not to be the case. :doc:`BuildingLibcxx` + describes those two ways of building. Please migrate over to the appropriate build + instructions as soon as possible. + + All other ways to build are deprecated and will not be supported in the next release. + We understand that making these changes can be daunting. For that reason, here's a + summary of how to migrate from the two most common ways to build: + + - If you were rooting your CMake invocation at ``/llvm`` and passing ``-DLLVM_ENABLE_PROJECTS=<...>`` + (which was the previously advertised way to build the runtimes), please simply root your CMake invocation at + ``/runtimes`` and pass ``-DLLVM_ENABLE_RUNTIMES=<...>``. + + - If you were doing multiple CMake invocations, e.g. one rooted at ``/libcxx`` and one rooted + at ``/libcxxabi`` (this used to be called a "Standalone build"), please move them to a + single invocation like so: + + .. code-block:: bash + + $ cmake -S /libcxx -B libcxx-build + $ cmake -S /libcxxabi -B libcxxabi-build + + should become + + .. code-block:: bash + + $ cmake -S /runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" + +- Support for building the runtimes using the GCC 32 bit multilib flag (``-m32``) has been removed. Support + for this had been flaky for a while, and we didn't know of anyone depending on this. Instead, please perform + a normal cross-compilation of the runtimes using the appropriate target, such as passing the following to + your bootstrapping build: + + .. code-block:: bash + + -DLLVM_RUNTIME_TARGETS=i386-unknown-linux + +- Libc++, libc++abi, and libunwind will not be built with ``-fPIC`` by default anymore. + If you want to build those runtimes with position-independent code, please specify + ``-DCMAKE_POSITION_INDEPENDENT_CODE=ON`` explicitly when configuring the build, or + ``-DRUNTIMES__CMAKE_POSITION_INDEPENDENT_CODE=ON`` if using the + bootstrapping build. + +- The ``{LIBCXX,LIBCXXABI,LIBUNWIND}_TARGET_TRIPLE``, ``{LIBCXX,LIBCXXABI,LIBUNWIND}_SYSROOT`` and + ``{LIBCXX,LIBCXXABI,LIBUNWIND}_GCC_TOOLCHAIN`` CMake variables are deprecated. Instead, please use + the ``CMAKE_CXX_COMPILER_TARGET``, ``CMAKE_SYSROOT`` and ``CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN`` + variables provided by CMake. diff --git a/docs/Status/Cxx14.rst b/docs/Status/Cxx14.rst new file mode 100644 index 000000000..0557bdc28 --- /dev/null +++ b/docs/Status/Cxx14.rst @@ -0,0 +1,50 @@ +.. _cxx14-status: + +================================ +libc++ C++14 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y". + +The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol). + +In August 2014, this draft was approved by ISO as C++14. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + + +.. _paper-status-cxx14: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx14Papers.csv + :header-rows: 1 + :widths: auto + + +.. _issues-status-cxx14: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx14Issues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/Cxx14Issues.csv b/docs/Status/Cxx14Issues.csv new file mode 100644 index 000000000..02da3e71b --- /dev/null +++ b/docs/Status/Cxx14Issues.csv @@ -0,0 +1,157 @@ +"Issue #","Issue Name","Meeting","Status" +"`1214 `__","Insufficient/inconsistent key immutability requirements for associative containers","Kona","|Complete|" +"`2009 `__","Reporting out-of-bound values on numeric string conversions","Kona","|Complete|" +"`2010 `__","``is_*``\ traits for binding operations can't be meaningfully specialized","Kona","|Complete|" +"`2015 `__","Incorrect pre-conditions for some type traits","Kona","|Complete|" +"`2021 `__","Further incorrect usages of result_of","Kona","|Complete|" +"`2028 `__","messages_base::catalog overspecified","Kona","|Complete|" +"`2033 `__","Preconditions of reserve, shrink_to_fit, and resize functions","Kona","|Complete|" +"`2039 `__","Issues with std::reverse and std::copy_if","Kona","|Complete|" +"`2044 `__","No definition of ""Stable"" for copy algorithms","Kona","|Complete|" +"`2045 `__","forward_list::merge and forward_list::splice_after with unequal allocators","Kona","|Complete|" +"`2047 `__","Incorrect ""mixed"" move-assignment semantics of unique_ptr","Kona","|Complete|" +"`2050 `__","Unordered associative containers do not use allocator_traits to define member types","Kona","|Complete|" +"`2053 `__","Errors in regex bitmask types","Kona","|Complete|" +"`2061 `__","make_move_iterator and arrays","Kona","|Complete|" +"`2064 `__","More noexcept issues in basic_string","Kona","|Complete|" +"`2065 `__","Minimal allocator interface","Kona","|Complete|" +"`2067 `__","packaged_task should have deleted copy c'tor with const parameter","Kona","|Complete|" +"`2069 `__","Inconsistent exception spec for basic_string move constructor","Kona","|Complete|" +"`2096 `__","Incorrect constraints of future::get in regard to MoveAssignable","Kona","|Complete|" +"`2102 `__","Why is std::launch an implementation-defined type?","Kona","|Complete|" +"","","","" +"`2071 `__","std::valarray move-assignment","Portland","|Complete|" +"`2074 `__","Off by one error in std::reverse_copy","Portland","|Complete|" +"`2081 `__","Allocator requirements should include CopyConstructible","Portland","|Complete|" +"`2083 `__","const-qualification on weak_ptr::owner_before","Portland","|Complete|" +"`2086 `__","Overly generic type support for math functions","Portland","|Complete|" +"`2099 `__","Unnecessary constraints of va_start() usage","Portland","|Complete|" +"`2103 `__","std::allocator_traits>::propagate_on_container_move_assignment","Portland","|Complete|" +"`2105 `__","Inconsistent requirements on ``const_iterator``'s value_type","Portland","|Complete|" +"`2110 `__","remove can't swap but note says it might","Portland","|Complete|" +"`2123 `__","merge() allocator requirements for lists versus forward lists","Portland","|Complete|" +"`2005 `__","unordered_map::insert(T&&) protection should apply to map too","Portland","|Complete|" +"`2011 `__","Unexpected output required of strings","Portland","|Complete|" +"`2048 `__","Unnecessary mem_fn overloads","Portland","|Complete|" +"`2049 `__","``is_destructible``\ is underspecified","Portland","|Complete|" +"`2056 `__","future_errc enums start with value 0 (invalid value for broken_promise)","Portland","|Complete|" +"`2058 `__","valarray and begin/end","Portland","|Complete|" +"","","","" +"`2091 `__","Misplaced effect in m.try_lock_for()","Bristol","|Complete|" +"`2092 `__","Vague Wording for condition_variable_any","Bristol","|Complete|" +"`2093 `__","Throws clause of condition_variable::wait with predicate","Bristol","|Complete|" +"`2094 `__","duration conversion overflow shouldn't participate in overload resolution","Bristol","|Complete|" +"`2122 `__","merge() stability for lists versus forward lists","Bristol","|Complete|" +"`2128 `__","Absence of global functions cbegin/cend","Bristol","|Complete|" +"`2145 `__","error_category default constructor","Bristol","|Complete|" +"`2147 `__","Unclear hint type in Allocator's allocate function","Bristol","|Complete|" +"`2148 `__","Hashing enums should be supported directly by std::hash","Bristol","|Complete|" +"`2149 `__","Concerns about 20.8/5","Bristol","|Complete|" +"`2162 `__","allocator_traits::max_size missing noexcept","Bristol","|Complete|" +"`2163 `__","nth_element requires inconsistent post-conditions","Bristol","|Complete|" +"`2169 `__","Missing reset() requirements in unique_ptr specialization","Bristol","|Complete|" +"`2172 `__","Does ``atomic_compare_exchange_*``\ accept v == nullptr arguments?","Bristol","|Complete|" +"`2080 `__","Specify when once_flag becomes invalid","Bristol","|Complete|" +"`2098 `__","promise throws clauses","Bristol","|Complete|" +"`2109 `__","Incorrect requirements for hash specializations","Bristol","|Complete|" +"`2130 `__","missing ordering constraints for fences","Bristol","|Complete|" +"`2138 `__","atomic_flag::clear ordering constraints","Bristol","|Complete|" +"`2140 `__","notify_all_at_thread_exit synchronization","Bristol","|Complete|" +"`2144 `__","Missing noexcept specification in type_index","Bristol","|Complete|" +"`2174 `__","wstring_convert::converted() should be noexcept","Bristol","|Complete|" +"`2175 `__","string_convert and wbuffer_convert validity","Bristol","|Complete|" +"`2176 `__","Special members for wstring_convert and wbuffer_convert","Bristol","|Complete|" +"`2177 `__","Requirements on Copy/MoveInsertable","Bristol","|Complete|" +"`2185 `__","Missing throws clause for future/shared_future::wait_for/wait_until","Bristol","|Complete|" +"`2187 `__","vector is missing emplace and emplace_back member functions","Bristol","|Complete|" +"`2190 `__","ordering of condition variable operations, reflects Posix discussion","Bristol","|Complete|" +"`2196 `__","Specification of ``is_*[copy/move]_[constructible/assignable]``\ unclear for non-referencable types","Bristol","|Complete|" +"`2197 `__","Specification of ``is_[un]signed``\ unclear for non-arithmetic types","Bristol","|Complete|" +"`2200 `__","Data race avoidance for all containers, not only for sequences","Bristol","|Complete|" +"`2203 `__","scoped_allocator_adaptor uses wrong argument types for piecewise construction","Bristol","|Complete|" +"`2207 `__","basic_string::at should not have a Requires clause","Bristol","|Complete|" +"`2209 `__","assign() overspecified for sequence containers","Bristol","|Complete|" +"`2210 `__","Missing allocator-extended constructor for allocator-aware containers","Bristol","|Complete|" +"`2211 `__","Replace ambiguous use of ""Allocator"" in container requirements","Bristol","|Complete|" +"`2222 `__","Inconsistency in description of forward_list::splice_after single-element overload","Bristol","|Complete|" +"`2225 `__","Unrealistic header inclusion checks required","Bristol","|Complete|" +"`2229 `__","Standard code conversion facets underspecified","Bristol","|Complete|" +"`2231 `__","DR 704 removes complexity guarantee for clear()","Bristol","|Complete|" +"`2235 `__","Undefined behavior without proper requirements on basic_string constructors","Bristol","|Complete|" +"","","","" +"`2141 `__","common_type trait produces reference types","Chicago","|Complete|" +"`2246 `__","unique_ptr assignment effects w.r.t. deleter","Chicago","|Complete|" +"`2247 `__","Type traits and std::nullptr_t","Chicago","|Complete|" +"`2085 `__","Wrong description of effect 1 of basic_istream::ignore","Chicago","|Complete|" +"`2087 `__","iostream_category() and noexcept","Chicago","|Complete|" +"`2143 `__","ios_base::xalloc should be thread-safe","Chicago","|Complete|" +"`2150 `__","Unclear specification of find_end","Chicago","|Complete|" +"`2180 `__","Exceptions from std::seed_seq operations","Chicago","|Complete|" +"`2194 `__","Impossible container requirements for adaptor types","Chicago","|Complete|" +"`2013 `__","Do library implementers have the freedom to add constexpr?","Chicago","|Complete|" +"`2018 `__","regex_traits::isctype Returns clause is wrong","Chicago","|Complete|" +"`2078 `__","Throw specification of async() incomplete","Chicago","|Complete|" +"`2097 `__","packaged_task constructors should be constrained","Chicago","|Complete|" +"`2100 `__","Timed waiting functions cannot timeout if launch::async policy used","Chicago","|Complete|" +"`2120 `__","What should async do if neither 'async' nor 'deferred' is set in policy?","Chicago","|Complete|" +"`2159 `__","atomic_flag initialization","Chicago","|Complete|" +"`2275 `__","Why is forward_as_tuple not constexpr?","Chicago","|Complete|" +"`2284 `__","Inconsistency in allocator_traits::max_size","Chicago","|Complete|" +"`2298 `__","``is_nothrow_constructible``\ is always false because of create<>","Chicago","|Complete|" +"`2300 `__","Redundant sections for map and multimap members should be removed","Chicago","|Complete|" +"NB comment: GB9","Remove gets from C++14","Chicago","|Complete|" +"","","","" +"`2135 `__","Unclear requirement for exceptions thrown in condition_variable::wait()","Issaquah","|Complete|" +"`2291 `__","std::hash is vulnerable to collision DoS attack","Issaquah","|Complete|" +"`2142 `__","packaged_task::operator() synchronization too broad?","Issaquah","|Complete|" +"`2240 `__","Probable misuse of term ""function scope"" in [thread.condition]","Issaquah","|Complete|" +"`2252 `__","Strong guarantee on vector::push_back() still broken with C++11?","Issaquah","|Complete|" +"`2257 `__","Simplify container requirements with the new algorithms","Issaquah","|Complete|" +"`2268 `__","Setting a default argument in the declaration of a member function assign of std::basic_string","Issaquah","|Complete|" +"`2271 `__","regex_traits::lookup_classname specification unclear","Issaquah","|Complete|" +"`2272 `__","quoted should use char_traits::eq for character comparison","Issaquah","|Complete|" +"`2278 `__","User-defined literals for Standard Library types","Issaquah","|Complete|" +"`2280 `__","begin / end for arrays should be constexpr and noexcept","Issaquah","|Complete|" +"`2285 `__","make_reverse_iterator","Issaquah","|Complete|" +"`2299 `__","Effects of inaccessible ``key_compare::is_transparent``\ type are not clear","Issaquah","|Complete|" +"`1450 `__","Contradiction in regex_constants","Issaquah","|Complete|" +"`2003 `__","String exception inconsistency in erase.","Issaquah","|Complete|" +"`2112 `__","User-defined classes that cannot be derived from","Issaquah","|Complete|" +"`2132 `__","std::function ambiguity","Issaquah","|Complete|" +"`2182 `__","``Container::[const_]reference`` types are misleadingly specified","Issaquah","|Complete|" +"`2188 `__","Reverse iterator does not fully support targets that overload operator&","Issaquah","|Complete|" +"`2193 `__","Default constructors for standard library containers are explicit","Issaquah","|Complete|" +"`2205 `__","Problematic postconditions of regex_match and regex_search","Issaquah","|Complete|" +"`2213 `__","Return value of std::regex_replace","Issaquah","|Complete|" +"`2258 `__","a.erase(q1, q2) unable to directly return q2","Issaquah","|Complete|" +"`2263 `__","Comparing iterators and allocator pointers with different const-character","Issaquah","|Complete|" +"`2293 `__","Wrong facet used by num_put::do_put","Issaquah","|Complete|" +"`2301 `__","Why is std::tie not constexpr?","Issaquah","|Complete|" +"`2304 `__","Complexity of count in unordered associative containers","Issaquah","|Complete|" +"`2306 `__","match_results::reference should be value_type&, not const value_type&","Issaquah","|Complete|" +"`2308 `__","Clarify container destructor requirements w.r.t. std::array","Issaquah","|Complete|" +"`2313 `__","tuple_size should always derive from integral_constant","Issaquah","|Complete|" +"`2314 `__","apply() should return decltype(auto) and use decay_t before tuple_size","Issaquah","|Complete|" +"`2315 `__","weak_ptr should be movable","Issaquah","|Complete|" +"`2316 `__","weak_ptr::lock() should be atomic","Issaquah","|Complete|" +"`2317 `__","The type property queries should be UnaryTypeTraits returning size_t","Issaquah","|Complete|" +"`2320 `__","select_on_container_copy_construction() takes allocators, not containers","Issaquah","|Complete|" +"`2322 `__","Associative(initializer_list, stuff) constructors are underspecified","Issaquah","|Complete|" +"`2323 `__","vector::resize(n, t)'s specification should be simplified","Issaquah","|Complete|" +"`2324 `__","Insert iterator constructors should use addressof()","Issaquah","|Complete|" +"`2329 `__","regex_match()/regex_search() with match_results should forbid temporary strings","Issaquah","|Complete|" +"`2330 `__","regex(""meow"", regex::icase) is technically forbidden but should be permitted","Issaquah","|Complete|" +"`2332 `__","regex_iterator/regex_token_iterator should forbid temporary regexes","Issaquah","|Complete|" +"`2339 `__","Wording issue in nth_element","Issaquah","|Complete|" +"`2341 `__","Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)","Issaquah","|Complete|" +"`2344 `__","quoted()'s interaction with padding is unclear","Issaquah","|Complete|" +"`2346 `__","integral_constant's member functions should be marked noexcept","Issaquah","|Complete|" +"`2350 `__","min, max, and minmax should be constexpr","Issaquah","|Complete|" +"`2356 `__","Stability of erasure in unordered associative containers","Issaquah","|Complete|" +"`2357 `__","Remaining ""Assignable"" requirement","Issaquah","|Complete|" +"`2359 `__","How does regex_constants::nosubs affect basic_regex::mark_count()?","Issaquah","|Complete|" +"`2360 `__","``reverse_iterator::operator*()``\ is unimplementable","Issaquah","|Complete|" +"`2104 `__","unique_lock move-assignment should not be noexcept","Issaquah","|Complete|" +"`2186 `__","Incomplete action on async/launch::deferred","Issaquah","|Complete|" +"`2075 `__","Progress guarantees, lock-free property, and scheduling assumptions","Issaquah","|Complete|" +"`2288 `__","Inconsistent requirements for shared mutexes","Issaquah","|Complete|" diff --git a/docs/Status/Cxx14Papers.csv b/docs/Status/Cxx14Papers.csv new file mode 100644 index 000000000..0e5ba7f99 --- /dev/null +++ b/docs/Status/Cxx14Papers.csv @@ -0,0 +1,32 @@ +"Paper #","Group","Paper Name","Meeting","Status","First released version" +"`3346 `__","LWG","Terminology for Container Element Requirements - Rev 1","Kona","|Complete|","3.4" +"","","","","","" +"`3421 `__","LWG","Making Operator Functors greater<>","Portland","|Complete|","3.4" +"`3462 `__","LWG","std::result_of and SFINAE","Portland","|Complete|","3.4" +"`3469 `__","LWG","Constexpr Library Additions: chrono, v3","Portland","|Complete|","3.4" +"`3470 `__","LWG","Constexpr Library Additions: containers, v2","Portland","|Complete|","3.4" +"`3471 `__","LWG","Constexpr Library Additions: utilities, v3","Portland","|Complete|","3.4" +"`3302 `__","LWG","Constexpr Library Additions: complex, v2","Portland","|Complete|","3.4" +"","","","","","" +"`3545 `__","LWG","An Incremental Improvement to integral_constant","Bristol","|Complete|","3.4" +"`3644 `__","LWG","Null Forward Iterators","Bristol","|Complete|","3.4" +"`3668 `__","LWG","std::exchange()","Bristol","|Complete|","3.4" +"`3658 `__","LWG","Compile-time integer sequences","Bristol","|Complete|","3.4" +"`3670 `__","LWG","Addressing Tuples by Type","Bristol","|Complete|","3.4" +"`3671 `__","LWG","Making non-modifying sequence operations more robust","Bristol","|Complete|","3.4" +"`3656 `__","LWG","make_unique","Bristol","|Complete|","3.4" +"`3654 `__","LWG","Quoted Strings","Bristol","|Complete|","3.4" +"`3642 `__","LWG","User-defined Literals","Bristol","|Complete|","3.4" +"`3655 `__","LWG","TransformationTraits Redux (excluding part 4)","Bristol","|Complete|","3.4" +"`3657 `__","LWG","Adding heterogeneous comparison lookup to associative containers","Bristol","|Complete|","3.4" +"`3672 `__","LWG","A proposal to add a utility class to represent optional objects","Bristol","*Removed from Draft Standard*","n/a" +"`3669 `__","LWG","Fixing constexpr member functions without const","Bristol","|Complete|","3.4" +"`3662 `__","LWG","C++ Dynamic Arrays (dynarray)","Bristol","*Removed from Draft Standard*","n/a" +"`3659 `__","SG1","Shared Locking in C++","Bristol","|Complete|","3.4" +"","","","","","" +"`3779 `__","LWG","User-defined Literals for std::complex","Chicago","|Complete|","3.4" +"`3789 `__","LWG","Constexpr Library Additions: functional","Chicago","|Complete|","3.4" +"","","","","","" +"`3924 `__","LWG","Discouraging rand() in C++14","Issaquah","|Complete|","3.5" +"`3887 `__","LWG","Consistent Metafunction Aliases","Issaquah","|Complete|","3.5" +"`3891 `__","SG1","A proposal to rename shared_mutex to shared_timed_mutex","Issaquah","|Complete|","3.5" diff --git a/docs/Status/Cxx17.rst b/docs/Status/Cxx17.rst new file mode 100644 index 000000000..26bf0ad6b --- /dev/null +++ b/docs/Status/Cxx17.rst @@ -0,0 +1,55 @@ +.. _cxx17-status: + +================================ +libc++ C++17 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z". +In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx17: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx17Papers.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``. + .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. + + +.. _issues-status-cxx17: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx17Issues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/Cxx17Issues.csv b/docs/Status/Cxx17Issues.csv new file mode 100644 index 000000000..27f0e660d --- /dev/null +++ b/docs/Status/Cxx17Issues.csv @@ -0,0 +1,318 @@ +"Issue #","Issue Name","Meeting","Status","First released version" +"`2016 `__","Allocators must be no-throw swappable","Urbana","|Complete|","" +"`2118 `__","``unique_ptr``\ for array does not support cv qualification conversion of actual argument","Urbana","|Complete|","" +"`2170 `__","Aggregates cannot be ``DefaultConstructible``\ ","Urbana","|Complete|","" +"`2308 `__","Clarify container destructor requirements w.r.t. ``std::array``\ ","Urbana","|Complete|","" +"`2340 `__","Replacement allocation functions declared as inline","Urbana","|Complete|","" +"`2354 `__","Unnecessary copying when inserting into maps with braced-init syntax","Urbana","|Complete|","" +"`2377 `__","``std::align``\ requirements overly strict","Urbana","|Complete|","" +"`2396 `__","``underlying_type``\ doesn't say what to do for an incomplete enumeration type","Urbana","|Complete|","" +"`2399 `__","``shared_ptr``\ 's constructor from ``unique_ptr``\ should be constrained","Urbana","|Complete|","" +"`2400 `__","``shared_ptr``\ 's ``get_deleter()``\ should use ``addressof()``\ ","Urbana","|Complete|","" +"`2401 `__","``std::function``\ needs more noexcept","Urbana","|Complete|","" +"`2404 `__","``mismatch()``\ 's complexity needs to be updated","Urbana","|Complete|","" +"`2408 `__","SFINAE-friendly ``common_type``\ / ``iterator_traits``\ is missing in C++14","Urbana","|Complete|","" +"","","","","" +"`2106 `__","``move_iterator``\ wrapping iterators returning prvalues","Urbana","|Complete|","" +"`2129 `__","User specializations of ``std::initializer_list``\ ","Urbana","|Complete|","" +"`2212 `__","``tuple_size``\ for ``const pair``\ request header","Urbana","|Complete|","" +"`2217 `__","``operator==(sub_match, string)``\ slices on embedded '\0's","Urbana","|Complete|","" +"`2230 `__","""see below"" for ``initializer_list``\ constructors of unordered containers","Urbana","|Complete|","" +"`2233 `__","``bad_function_call::what()``\ unhelpful","Urbana","|Complete|","" +"`2266 `__","``vector``\ and ``deque``\ have incorrect insert requirements","Urbana","|Complete|","" +"`2325 `__","``minmax_element()``\ 's behavior differing from ``max_element()``\ 's should be noted","Urbana","|Complete|","" +"`2361 `__","Apply 2299 resolution throughout library","Urbana","|Complete|","" +"`2365 `__","Missing noexcept in ``shared_ptr::shared_ptr(nullptr_t)``\ ","Urbana","|Complete|","" +"`2376 `__","``bad_weak_ptr::what()``\ overspecified","Urbana","|Complete|","" +"`2387 `__","More nested types that must be accessible and unambiguous","Urbana","|Complete|","" +"","","","","" +"`2059 `__","C++0x ambiguity problem with map::erase","Lenexa","|Complete|","" +"`2063 `__","Contradictory requirements for string move assignment","Lenexa","|Complete|","" +"`2076 `__","Bad CopyConstructible requirement in set constructors","Lenexa","|Complete|","" +"`2160 `__","Unintended destruction ordering-specification of resize","Lenexa","|Complete|","" +"`2168 `__","Inconsistent specification of uniform_real_distribution constructor","Lenexa","|Complete|","" +"`2239 `__","min/max/minmax requirements","Lenexa","|Complete|","" +"`2364 `__","deque and vector pop_back don't specify iterator invalidation requirements","Lenexa","|Complete|","" +"`2369 `__","constexpr max(initializer_list) vs max_element","Lenexa","|Complete|","" +"`2378 `__","Behaviour of standard exception types","Lenexa","|Complete|","" +"`2403 `__","stof() should call strtof() and wcstof()","Lenexa","|Complete|","" +"`2406 `__","negative_binomial_distribution should reject p == 1","Lenexa","|Complete|","" +"`2407 `__","packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit","Lenexa","|Complete|","" +"`2411 `__","shared_ptr is only contextually convertible to bool","Lenexa","|Complete|","" +"`2415 `__","Inconsistency between unique_ptr and shared_ptr","Lenexa","|Complete|","" +"`2420 `__","function does not discard the return value of the target object","Lenexa","|Complete|","" +"`2425 `__","``operator delete(void*, size_t)``\ doesn't invalidate pointers sufficiently","Lenexa","|Complete|","" +"`2427 `__","Container adaptors as sequence containers, redux","Lenexa","|Complete|","" +"`2428 `__","""External declaration"" used without being defined","Lenexa","|Complete|","" +"`2433 `__","``uninitialized_copy()``\ /etc. should tolerate overloaded operator&","Lenexa","|Complete|","" +"`2434 `__","``shared_ptr::use_count()``\ is efficient","Lenexa","|Complete|","" +"`2437 `__","``iterator_traits::reference``\ can and can't be void","Lenexa","|Complete|","" +"`2438 `__","``std::iterator``\ inheritance shouldn't be mandated","Lenexa","|Complete|","" +"`2439 `__","``unique_copy()``\ sometimes can't fall back to reading its output","Lenexa","|Complete|","" +"`2440 `__","``seed_seq::size()``\ should be noexcept","Lenexa","|Complete|","" +"`2442 `__","``call_once()``\ shouldn't DECAY_COPY()","Lenexa","|Complete|","" +"`2448 `__","Non-normative Container destructor specification","Lenexa","|Complete|","" +"`2454 `__","Add ``raw_storage_iterator::base()``\ member","Lenexa","|Complete|","" +"`2455 `__","Allocator default construction should be allowed to throw","Lenexa","|Complete|","" +"`2458 `__","N3778 and new library deallocation signatures","Lenexa","|Complete|","" +"`2459 `__","``std::polar``\ should require a non-negative rho","Lenexa","|Complete|","" +"`2464 `__","``try_emplace``\ and ``insert_or_assign``\ misspecified","Lenexa","|Complete|","" +"`2467 `__","``is_always_equal``\ has slightly inconsistent default","Lenexa","|Complete|","" +"`2470 `__","Allocator's destroy function should be allowed to fail to instantiate","Lenexa","|Complete|","" +"`2482 `__","[c.strings] Table 73 mentions nonexistent functions","Lenexa","|Complete|","" +"`2488 `__","Placeholders should be allowed and encouraged to be constexpr","Lenexa","|Complete|","" +"","","","","" +"`1169 `__","``num_get``\ not fully compatible with ``strto*``\ ","Kona","|Complete|","" +"`2072 `__","Unclear wording about capacity of temporary buffers","Kona","|Complete|","" +"`2101 `__","Some transformation types can produce impossible types","Kona","|Complete|","" +"`2111 `__","Which ``unexpected``\ /``terminate``\ handler is called from the exception handling runtime?","Kona","|Complete|","" +"`2119 `__","Missing ``hash``\ specializations for extended integer types","Kona","|Complete|","" +"`2127 `__","Move-construction with ``raw_storage_iterator``\ ","Kona","|Complete|","" +"`2133 `__","Attitude to overloaded comma for iterators","Kona","|Complete|","" +"`2156 `__","Unordered containers' ``reserve(n)``\ reserves for ``n-1``\ elements","Kona","|Complete|","" +"`2218 `__","Unclear how containers use ``allocator_traits::construct()``\ ","Kona","|Complete|","" +"`2219 `__","``*INVOKE*``\ -ing a pointer to member with a ``reference_wrapper``\ as the object expression","Kona","|Complete|","" +"`2224 `__","Ambiguous status of access to non-live objects","Kona","|Complete|","" +"`2234 `__","``assert()``\ should allow usage in constant expressions","Kona","|Complete|","" +"`2244 `__","Issue on ``basic_istream::seekg``\ ","Kona","|Complete|","" +"`2250 `__","Follow-up On Library Issue 2207","Kona","|Complete|","" +"`2259 `__","Issues in 17.6.5.5 rules for member functions","Kona","|Complete|","" +"`2273 `__","``regex_match``\ ambiguity","Kona","|Complete|","" +"`2336 `__","``is_trivially_constructible``\ /``is_trivially_assignable``\ traits are always false","Kona","|Complete|","" +"`2353 `__","``std::next``\ is over-constrained","Kona","|Complete|","" +"`2367 `__","``pair``\ and ``tuple``\ are not correctly implemented for ``is_constructible``\ with no args","Kona","|Complete|","" +"`2380 `__","May ````\ provide ``long ::abs(long)``\ and ``long long ::abs(long long)``\ ?","Kona","|Complete|","" +"`2384 `__","Allocator's ``deallocate``\ function needs better specification","Kona","|Complete|","" +"`2385 `__","``function::assign``\ allocator argument doesn't make sense","Kona","|Complete|","" +"`2435 `__","``reference_wrapper::operator()``\ 's Remark should be deleted","Kona","|Complete|","" +"`2447 `__","Allocators and ``volatile``\ -qualified value types","Kona","|Complete|","" +"`2462 `__","``std::ios_base::failure``\ is overspecified","Kona","|Complete|","" +"`2466 `__","``allocator_traits::max_size()``\ default behavior is incorrect","Kona","|Complete|","" +"`2469 `__","Wrong specification of Requires clause of ``operator[]``\ for ``map``\ and ``unordered_map``\ ","Kona","|Complete|","" +"`2473 `__","``basic_filebuf``\ 's relation to C ``FILE``\ semantics","Kona","|Complete|","" +"`2476 `__","``scoped_allocator_adaptor``\ is not assignable","Kona","|Complete|","" +"`2477 `__","Inconsistency of wordings in ``std::vector::erase()``\ and ``std::deque::erase()``\ ","Kona","|Complete|","" +"`2483 `__","``throw_with_nested()``\ should use ``is_final``\ ","Kona","|Complete|","" +"`2484 `__","``rethrow_if_nested()``\ is doubly unimplementable","Kona","|Complete|","" +"`2485 `__","``get()``\ should be overloaded for ``const tuple&&``\ ","Kona","|Complete|","" +"`2486 `__","``mem_fn()``\ should be required to use perfect forwarding","Kona","|Complete|","" +"`2487 `__","``bind()``\ should be ``const``\ -overloaded, not *cv*-overloaded","Kona","|Complete|","" +"`2489 `__","``mem_fn()``\ should be ``noexcept``\ ","Kona","|Complete|","" +"`2492 `__","Clarify requirements for ``comp``\ ","Kona","|Complete|","" +"`2495 `__","There is no such thing as an Exception Safety element","Kona","|Complete|","" +"","","","","" +"`2192 `__","Validity and return type of ``std::abs(0u)``\ is unclear","Jacksonville","|Complete|","" +"`2276 `__","Missing requirement on ``std::promise::set_exception``\ ","Jacksonville","|Complete|","" +"`2296 `__","``std::addressof``\ should be ``constexpr``\ ","Jacksonville","|Complete|","" +"`2450 `__","``(greater|less|greater_equal|less_equal)``\ do not yield a total order for pointers","Jacksonville","|Complete|","" +"`2520 `__","N4089 broke initializing ``unique_ptr``\ from a ``nullptr``\ ","Jacksonville","|Complete|","" +"`2522 `__","[fund.ts.v2] Contradiction in ``set_default_resource``\ specification","Jacksonville","|Complete|","" +"`2523 `__","``std::promise``\ synopsis shows two ``set_value_at_thread_exit()``\ 's for no apparent reason","Jacksonville","|Complete|","" +"`2537 `__","Constructors for ``priority_queue``\ taking allocators should call ``make_heap``\ ","Jacksonville","|Complete|","" +"`2539 `__","[fund.ts.v2] ``invocation_trait``\ definition definition doesn't work for surrogate call functions","Jacksonville","","" +"`2545 `__","Simplify wording for ``bind``\ without explicitly specified return type","Jacksonville","|Complete|","" +"`2557 `__","Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|","" +"`2558 `__","[fund.ts.v2] Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|","" +"`2559 `__","Error in LWG 2234's resolution","Jacksonville","|Complete|","" +"`2560 `__","``is_constructible``\ underspecified when applied to a function type","Jacksonville","|Complete|","" +"`2565 `__","``std::function``\ 's move constructor should guarantee nothrow for ``reference_wrapper``\ s and function pointers","Jacksonville","|Complete|","" +"`2566 `__","Requirements on the first template parameter of container adaptors","Jacksonville","|Complete|","" +"`2571 `__","|sect|\ [map.modifiers]/2 imposes nonsensical requirement on ``insert(InputIterator, InputIterator)``\ ","Jacksonville","|Complete|","" +"`2572 `__","The remarks for ``shared_ptr::operator*``\ should apply to *cv*-qualified ``void``\ as well","Jacksonville","|Complete|","" +"`2574 `__","[fund.ts.v2] ``std::experimental::function::operator=(F&&)``\ should be constrained","Jacksonville","|Complete|","" +"`2575 `__","[fund.ts.v2] ``experimental::function::assign``\ should be removed","Jacksonville","","" +"`2576 `__","``istream_iterator``\ and ``ostream_iterator``\ should use ``std::addressof``\ ","Jacksonville","|Complete|","" +"`2577 `__","``{shared,unique}_lock``\ should use ``std::addressof``\ ","Jacksonville","|Complete|","" +"`2579 `__","Inconsistency wrt Allocators in ``basic_string``\ assignment vs. ``basic_string::assign``\ ","Jacksonville","|Complete|","" +"`2581 `__","Specialization of ````\ variable templates should be prohibited","Jacksonville","|Complete|","" +"`2582 `__","|sect|\ [res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits","Jacksonville","|Complete|","" +"`2583 `__","There is no way to supply an allocator for ``basic_string(str, pos)``\ ","Jacksonville","|Complete|","" +"`2585 `__","``forward_list::resize(size_type, const value_type&)``\ effects incorrect","Jacksonville","|Complete|","" +"`2586 `__","Wrong value category used in ``scoped_allocator_adaptor::construct()``\ ","Jacksonville","|Complete|","" +"`2590 `__","Aggregate initialization for ``std::array``\ ","Jacksonville","|Complete|","" +"","","","","" +"`2181 `__","Exceptions from seed sequence operations","Oulu","|Complete|","" +"`2309 `__","mutex::lock() should not throw device_or_resource_busy","Oulu","|Complete|","" +"`2310 `__","Public exposition only member in std::array","Oulu","|Complete|","" +"`2312 `__","tuple's constructor constraints need to be phrased more precisely","Oulu","|Complete|","" +"`2328 `__","Rvalue stream extraction should use perfect forwarding","Oulu","|Complete|","" +"`2393 `__","std::function's Callable definition is broken","Oulu","|Complete|","" +"`2422 `__","``std::numeric_limits::is_modulo``\ description: ""most machines"" errata","Oulu","|Complete|","" +"`2426 `__","Issue about compare_exchange","Oulu","","" +"`2436 `__","Comparators for associative containers should always be CopyConstructible","Oulu","|Complete|","" +"`2441 `__","Exact-width atomic typedefs should be provided","Oulu","|Complete|","" +"`2451 `__","[fund.ts.v2] optional should 'forward' T's implicit conversions","Oulu","|Nothing To Do|","" +"`2509 `__","[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target","Oulu","|Complete|","" +"`2516 `__","[fund.ts.v2] Public ""exposition only"" members in observer_ptr","Oulu","","" +"`2542 `__","Missing const requirements for associative containers","Oulu","","" +"`2549 `__","Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references","Oulu","|Complete|","" +"`2550 `__","Wording of unordered container's clear() method complexity","Oulu","|Complete|","" +"`2551 `__","[fund.ts.v2] ""Exception safety"" cleanup in library fundamentals required","Oulu","|Complete|","" +"`2555 `__","[fund.ts.v2] No handling for over-aligned types in optional","Oulu","|Complete|","" +"`2573 `__","[fund.ts.v2] std::hash does not work for arrays","Oulu","","" +"`2596 `__","vector::data() should use addressof","Oulu","|Complete|","" +"`2667 `__","path::root_directory() description is confusing","Oulu","|Complete|","" +"`2669 `__","recursive_directory_iterator effects refers to non-existent functions","Oulu","|Complete|","" +"`2670 `__","system_complete refers to undefined variable 'base'","Oulu","|Complete|","" +"`2671 `__","Errors in Copy","Oulu","|Complete|","" +"`2673 `__","status() effects cannot be implemented as specified","Oulu","|Complete|","" +"`2674 `__","Bidirectional iterator requirement on path::iterator is very expensive","Oulu","|Complete|","" +"`2683 `__","filesystem::copy() says ""no effects""","Oulu","|Complete|","" +"`2684 `__","priority_queue lacking comparator typedef","Oulu","|Complete|","" +"`2685 `__","shared_ptr deleters must not throw on move construction","Oulu","|Complete|","" +"`2687 `__","{inclusive,exclusive}_scan misspecified","Oulu","","" +"`2688 `__","clamp misses preconditions and has extraneous condition on result","Oulu","|Complete|","" +"`2689 `__","Parallel versions of std::copy and std::move shouldn't be in order","Oulu","","" +"`2698 `__","Effect of assign() on iterators/pointers/references","Oulu","|Complete|","" +"`2704 `__","recursive_directory_iterator's members should require '``*this`` is dereferenceable'","Oulu","|Complete|","" +"`2706 `__","Error reporting for recursive_directory_iterator::pop() is under-specified","Oulu","|Complete|","" +"`2707 `__","path construction and assignment should have ""string_type&&"" overloads","Oulu","|Complete|","" +"`2709 `__","offsetof is unnecessarily imprecise","Oulu","","" +"`2710 `__","""Effects: Equivalent to ..."" doesn't count ""Synchronization:"" as determined semantics","Oulu","|Complete|","" +"`2711 `__","path is convertible from approximately everything under the sun","Oulu","|Complete|","" +"`2716 `__","Specification of shuffle and sample disallows lvalue URNGs","Oulu","|Complete|","" +"`2718 `__","Parallelism bug in [algorithms.parallel.exec] p2","Oulu","","" +"`2719 `__","permissions function should not be noexcept due to narrow contract","Oulu","|Complete|","" +"`2720 `__","permissions function incorrectly specified for symlinks","Oulu","|Complete|","" +"`2721 `__","remove_all has incorrect post conditions","Oulu","|Complete|","" +"`2723 `__","Do directory_iterator and recursive_directory_iterator become the end iterator upon error?","Oulu","|Complete|","" +"`2724 `__","The protected virtual member functions of memory_resource should be private","Oulu","","" +"`2725 `__","filesystem::exists(const path&, error_code&) error reporting","Oulu","|Complete|","" +"`2726 `__","``[recursive_]directory_iterator::increment(error_code&)`` is underspecified","Oulu","|Complete|","" +"`2727 `__","Parallel algorithms with constexpr specifier","Oulu","","" +"`2728 `__","status(p).permissions() and symlink_status(p).permissions() are not specified","Oulu","|Complete|","" +"","","","","" +"`2062 `__","Effect contradictions w/o no-throw guarantee of std::function swaps","Issaquah","|Complete|","" +"`2166 `__","Heap property underspecified?","Issaquah","","" +"`2221 `__","No formatted output operator for nullptr","Issaquah","|Complete|","" +"`2223 `__","shrink_to_fit effect on iterator validity","Issaquah","|Complete|","" +"`2261 `__","Are containers required to use their 'pointer' type internally?","Issaquah","","" +"`2394 `__","locale::name specification unclear - what is implementation-defined?","Issaquah","|Complete|","" +"`2460 `__","LWG issue 2408 and value categories","Issaquah","|Complete|","" +"`2468 `__","Self-move-assignment of library types","Issaquah","","" +"`2475 `__","Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs","Issaquah","|Complete|","" +"`2503 `__","multiline option should be added to syntax_option_type","Issaquah","|Complete|","" +"`2510 `__","Tag types should not be DefaultConstructible","Issaquah","|Complete|","" +"`2514 `__","Type traits must not be final","Issaquah","|Complete|","" +"`2518 `__","[fund.ts.v2] Non-member swap for propagate_const should call member swap","Issaquah","|Complete|","" +"`2519 `__","Iterator operator-= has gratuitous undefined behaviour","Issaquah","|Complete|","" +"`2521 `__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","","" +"`2525 `__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","","" +"`2527 `__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","","" +"`2531 `__","future::get should explicitly state that the shared state is released","Issaquah","","" +"`2534 `__","Constrain rvalue stream operators","Issaquah","|Complete|","" +"`2536 `__","What should do?","Issaquah","|Complete|","" +"`2540 `__","unordered_multimap::insert hint iterator","Issaquah","|Complete|","" +"`2543 `__","LWG 2148 (hash support for enum types) seems under-specified","Issaquah","|Complete|","" +"`2544 `__","``istreambuf_iterator(basic_streambuf* s)``\ effects unclear when s is 0","Issaquah","|Complete|","" +"`2556 `__","Wide contract for future::share()","Issaquah","|Complete|","" +"`2562 `__","Consistent total ordering of pointers by comparison functors","Issaquah","","" +"`2567 `__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","" +"`2568 `__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","","" +"`2569 `__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","" +"`2570 `__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","","" +"`2578 `__","Iterator requirements should reference iterator traits","Issaquah","|Complete|","" +"`2584 `__"," ECMAScript IdentityEscape is ambiguous","Issaquah","","" +"`2587 `__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567","" +"`2588 `__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","","" +"`2589 `__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|","" +"`2591 `__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|","" +"`2598 `__","addressof works on temporaries","Issaquah","|Complete|","" +"`2664 `__","operator/ (and other append) semantics not useful if argument has root","Issaquah","|Complete|","" +"`2665 `__","remove_filename() post condition is incorrect","Issaquah","|Complete|","" +"`2672 `__","Should ``is_empty``\ use error_code in its specification?","Issaquah","|Complete|","" +"`2678 `__","std::filesystem enum classes overspecified","Issaquah","|Complete|","" +"`2679 `__","Inconsistent Use of Effects and Equivalent To","Issaquah","|Complete|","" +"`2680 `__","Add ""Equivalent to"" to filesystem","Issaquah","|Complete|","" +"`2681 `__","filesystem::copy() cannot copy symlinks","Issaquah","|Complete|","" +"`2682 `__","filesystem::copy() won't create a symlink to a directory","Issaquah","|Complete|","" +"`2686 `__","Why is std::hash specialized for error_code, but not error_condition?","Issaquah","|Complete|","" +"`2694 `__","Application of LWG 436 accidentally deleted definition of ""facet""","Issaquah","|Complete|","" +"`2696 `__","Interaction between make_shared and enable_shared_from_this is underspecified","Issaquah","|Nothing To Do|","" +"`2699 `__","Missing restriction in [numeric.requirements]","Issaquah","|Complete|","" +"`2712 `__","copy_file(from, to, ...) has a number of unspecified error conditions","Issaquah","|Complete|","" +"`2722 `__","equivalent incorrectly specifies throws clause","Issaquah","|Complete|","" +"`2729 `__","Missing SFINAE on std::pair::operator=","Issaquah","|Complete|","" +"`2732 `__","Questionable specification of path::operator/= and path::append","Issaquah","|Complete|","" +"`2733 `__","[fund.ts.v2] gcd / lcm and bool","Issaquah","|Complete|","" +"`2735 `__","std::abs(short), std::abs(signed char) and others should return int instead of double in order to be compatible with C++98 and C","Issaquah","|Complete|","" +"`2736 `__","nullopt_t insufficiently constrained","Issaquah","|Complete|","" +"`2738 `__","``is_constructible``\ with void types","Issaquah","|Complete|","" +"`2739 `__","Issue with time_point non-member subtraction with an unsigned duration","Issaquah","|Complete|","" +"`2740 `__","constexpr optional::operator->","Issaquah","|Complete|","" +"`2742 `__","Inconsistent string interface taking string_view","Issaquah","|Complete|","" +"`2744 `__","any's in_place constructors","Issaquah","|Complete|","" +"`2745 `__","[fund.ts.v2] Implementability of LWG 2451","Issaquah","|Complete|","" +"`2747 `__","Possibly redundant std::move in [alg.foreach]","Issaquah","|Complete|","" +"`2748 `__","swappable traits for optionals","Issaquah","|Complete|","" +"`2749 `__","swappable traits for variants","Issaquah","|Complete|","" +"`2750 `__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|","" +"`2752 `__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","","" +"`2755 `__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|","" +"`2756 `__","C++ WP optional should 'forward' T's implicit conversions","Issaquah","|Complete|","" +"`2758 `__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|","" +"`2759 `__","gcd / lcm and bool for the WP","Issaquah","|Complete|","" +"`2760 `__","non-const basic_string::data should not invalidate iterators","Issaquah","|Complete|","" +"`2765 `__","Did LWG 1123 go too far?","Issaquah","|Complete|","" +"`2767 `__","not_fn call_wrapper can form invalid types","Issaquah","|Complete|","" +"`2769 `__","Redundant const in the return type of any_cast(const any&)","Issaquah","|Complete|","" +"`2771 `__","Broken Effects of some basic_string::compare functions in terms of basic_string_view","Issaquah","|Complete|","" +"`2773 `__","Making std::ignore constexpr","Issaquah","|Complete|","" +"`2777 `__","basic_string_view::copy should use char_traits::copy","Issaquah","|Complete|","" +"`2778 `__","basic_string_view is missing constexpr","Issaquah","|Complete|","" +"","","","","" +"`2260 `__","Missing requirement for Allocator::pointer","Kona","|Complete|","" +"`2676 `__","Provide filesystem::path overloads for File-based streams","Kona","|Complete|","" +"`2768 `__","any_cast and move semantics","Kona","|Complete|","" +"`2769 `__","Redundant const in the return type of any_cast(const any&)","Kona","|Complete|","" +"`2781 `__","Contradictory requirements for std::function and std::reference_wrapper","Kona","|Complete|","" +"`2782 `__","scoped_allocator_adaptor constructors must be constrained","Kona","|Complete|","" +"`2784 `__","Resolution to LWG 2484 is missing ""otherwise, no effects"" and is hard to parse","Kona","|Complete|","" +"`2785 `__","quoted should work with basic_string_view","Kona","|Complete|","" +"`2786 `__","Annex C should mention shared_ptr changes for array support","Kona","|Complete|","" +"`2787 `__","|sect|\ [file_status.cons] doesn't match class definition","Kona","|Complete|","" +"`2788 `__","basic_string range mutators unintentionally require a default constructible allocator","Kona","|Complete|","" +"`2789 `__","Equivalence of contained objects","Kona","|Complete|","" +"`2790 `__","Missing specification of istreambuf_iterator::operator->","Kona","|Complete|","" +"`2794 `__","Missing requirements for allocator pointers","Kona","|Nothing To Do|","" +"`2795 `__","|sect|\ [global.functions] provides incorrect example of ADL use","Kona","|Complete|","" +"`2796 `__","tuple should be a literal type","Kona","|Complete|","" +"`2801 `__","Default-constructibility of unique_ptr","Kona","|Complete|","" +"`2802 `__","shared_ptr constructor requirements for a deleter","Kona","|Complete|","" +"`2804 `__","Unconditional constexpr default constructor for istream_iterator","Kona","|Complete|","" +"`2806 `__","Base class of bad_optional_access","Kona","|Complete|","" +"`2807 `__","std::invoke should use ``std::is_nothrow_callable``\ ","Kona","|Complete|","" +"`2812 `__","Range access is available with ","Kona","|Complete|","" +"`2824 `__","list::sort should say that the order of elements is unspecified if an exception is thrown","Kona","|Complete|","" +"`2826 `__","string_view iterators use old wording","Kona","|Complete|","" +"`2834 `__","Resolution LWG 2223 is missing wording about end iterators","Kona","|Complete|","" +"`2835 `__","LWG 2536 seems to misspecify ","Kona","|Complete|","" +"`2837 `__","gcd and lcm should support a wider range of input values","Kona","|Complete|","" +"`2838 `__","is_literal_type specification needs a little cleanup","Kona","|Complete|","" +"`2842 `__","in_place_t check for optional::optional(U&&) should decay U","Kona","|Complete|","" +"`2850 `__","std::function move constructor does unnecessary work","Kona","|Complete|","" +"`2853 `__","Possible inconsistency in specification of erase in [vector.modifiers]","Kona","|Complete|","" +"`2855 `__","std::throw_with_nested(""string_literal"")","Kona","|Complete|","" +"`2857 `__","{variant,optional,any}::emplace should return the constructed value","Kona","|Complete|","" +"`2861 `__","basic_string should require that charT match traits::char_type","Kona","|Complete|","" +"`2866 `__","Incorrect derived classes constraints","Kona","|Nothing To Do|","" +"`2868 `__","Missing specification of bad_any_cast::what()","Kona","|Complete|","" +"`2872 `__","Add definition for direct-non-list-initialization","Kona","|Complete|","" +"`2873 `__","Add noexcept to several shared_ptr related functions","Kona","|Complete|","" +"`2874 `__","Constructor ``shared_ptr::shared_ptr(Y*)``\ should be constrained","Kona","|Complete|","13.0" +"`2875 `__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|","" +"`2876 `__","``shared_ptr::shared_ptr(const weak_ptr&)``\ constructor should be constrained","Kona","","" +"`2878 `__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|","" +"`2890 `__","The definition of 'object state' applies only to class types","Kona","|Complete|","" +"`2900 `__","The copy and move constructors of optional are not constexpr","Kona","|Complete|","" +"`2903 `__","The form of initialization for the emplace-constructors is not specified","Kona","|Complete|","" +"`2904 `__","Make variant move-assignment more exception safe","Kona","|Complete|","" +"`2905 `__","is_constructible_v, P, D const &> should be false when D is not copy constructible","Kona","|Complete|","" +"`2908 `__","The less-than operator for shared pointers could do more","Kona","|Complete|","" +"`2911 `__","An is_aggregate type trait is needed","Kona","|Complete|","" +"`2921 `__","packaged_task and type-erased allocators","Kona","|Complete|","" +"`2934 `__","optional doesn't compare with T","Kona","|Complete|","" +"","","","","" +"`2901 `__","Variants cannot properly support allocators","Toronto","|Complete|","" +"`2955 `__","``to_chars / from_chars``\ depend on ``std::string``\ ","Toronto","Resolved by `P0682R1 `__","" +"`2956 `__","``filesystem::canonical()``\ still defined in terms of ``absolute(p, base)``\ ","Toronto","|Complete|","" diff --git a/docs/Status/Cxx17Papers.csv b/docs/Status/Cxx17Papers.csv new file mode 100644 index 000000000..87991643c --- /dev/null +++ b/docs/Status/Cxx17Papers.csv @@ -0,0 +1,113 @@ +"Paper #","Group","Paper Name","Meeting","Status","First released version" +"`N3911 `__","LWG","TransformationTrait Alias ``void_t``\ .","Urbana","|Complete|","3.6" +"`N4089 `__","LWG","Safe conversions in ``unique_ptr``\ .","Urbana","|In Progress|","3.9" +"`N4169 `__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7" +"`N4190 `__","LWG","Removing auto_ptr, random_shuffle(), And Old Stuff.","Urbana","|In Progress|","" +"`N4258 `__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7" +"`N4259 `__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7" +"`N4277 `__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2" +"`N4279 `__","LWG","Improved insertion interface for unique-key maps.","Urbana","|Complete|","3.7" +"`N4280 `__","LWG","Non-member size() and more","Urbana","|Complete|","3.6" +"`N4284 `__","LWG","Contiguous Iterators.","Urbana","|Complete|","3.6" +"`N4285 `__","CWG","Cleanup for exception-specification and throw-expression.","Urbana","|Complete|","4.0" +"","","","","","" +"`N4387 `__","LWG","improving pair and tuple","Lenexa","|Complete|","4.0" +"`N4389 `__","LWG","bool_constant","Lenexa","|Complete|","3.7" +"`N4508 `__","LWG","shared_mutex for C++17","Lenexa","|Complete|","3.7" +"`N4366 `__","LWG","LWG 2228 missing SFINAE rule","Lenexa","|Complete|","3.1" +"`N4510 `__","LWG","Minimal incomplete type support for standard containers, revision 4","Lenexa","|Complete|","3.6" +"","","","","","" +"`P0004R1 `__","LWG","Remove Deprecated iostreams aliases.","Kona","|Complete|","3.8" +"`P0006R0 `__","LWG","Adopt Type Traits Variable Templates for C++17.","Kona","|Complete|","3.8" +"`P0092R1 `__","LWG","Polishing ","Kona","|Complete|","3.8" +"`P0007R1 `__","LWG","Constant View: A proposal for a ``std::as_const``\ helper function template.","Kona","|Complete|","3.8" +"`P0156R0 `__","LWG","Variadic lock_guard(rev 3).","Kona","*Reverted in Kona*","3.9" +"`P0074R0 `__","LWG","Making ``std::owner_less``\ more flexible","Kona","|Complete|","3.8" +"`P0013R1 `__","LWG","Logical type traits rev 2","Kona","|Complete|","3.8" +"","","","","","" +"`P0024R2 `__","LWG","The Parallelism TS Should be Standardized","Jacksonville","","" +"`P0226R1 `__","LWG","Mathematical Special Functions for C++17","Jacksonville","","" +"`P0220R1 `__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|In Progress|","" +"`P0218R1 `__","LWG","Adopt the File System TS for C++17","Jacksonville","|Complete|","7.0" +"`P0033R1 `__","LWG","Re-enabling shared_from_this","Jacksonville","|Complete|","3.9" +"`P0005R4 `__","LWG","Adopt not_fn from Library Fundamentals 2 for C++17","Jacksonville","|Complete|","3.9" +"`P0152R1 `__","LWG","constexpr ``atomic::is_always_lock_free``\ ","Jacksonville","|Complete|","3.9" +"`P0185R1 `__","LWG","Adding [nothrow-]swappable traits","Jacksonville","|Complete|","3.9" +"`P0253R1 `__","LWG","Fixing a design mistake in the searchers interface","Jacksonville","|Complete|","3.9" +"`P0025R0 `__","LWG","An algorithm to ""clamp"" a value between a pair of boundary values","Jacksonville","|Complete|","3.9" +"`P0154R1 `__","LWG","constexpr std::hardware_{constructive,destructive}_interference_size","Jacksonville","","" +"`P0030R1 `__","LWG","Proposal to Introduce a 3-Argument Overload to std::hypot","Jacksonville","|Complete|","3.9" +"`P0031R0 `__","LWG","A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access","Jacksonville","|Complete|","4.0" +"`P0272R1 `__","LWG","Give ``std::string``\ a non-const ``.data()``\ member function","Jacksonville","|Complete|","3.9" +"`P0077R2 `__","LWG","``is_callable``\ , the missing INVOKE related trait","Jacksonville","|Complete|","3.9" +"","","","","","" +"`p0032r3 `__","LWG","Homogeneous interface for variant, any and optional","Oulu","|Complete|","4.0" +"`p0040r3 `__","LWG","Extending memory management tools","Oulu","|Complete|","4.0" +"`p0063r3 `__","LWG","C++17 should refer to C11 instead of C99","Oulu","|Complete|","7.0" +"`p0067r3 `__","LWG","Elementary string conversions","Oulu","Now `P0067R5 `__","n/a" +"`p0083r3 `__","LWG","Splicing Maps and Sets","Oulu","|Complete|","8.0" +"`p0084r2 `__","LWG","Emplace Return Type","Oulu","|Complete|","4.0" +"`p0088r3 `__","LWG","Variant: a type-safe union for C++17","Oulu","|Complete|","4.0" +"`p0137r1 `__","CWG","Core Issue 1776: Replacement of class objects containing reference members","Oulu","|Complete|","6.0" +"`p0163r0 `__","LWG","shared_ptr::weak_type","Oulu","|Complete|","3.9" +"`p0174r2 `__","LWG","Deprecating Vestigial Library Parts in C++17","Oulu","|Partial|","" +"`p0175r1 `__","LWG","Synopses for the C library","Oulu","","" +"`p0180r2 `__","LWG","Reserve a New Library Namespace for Future Standardization","Oulu","|Nothing To Do|","n/a" +"`p0181r1 `__","LWG","Ordered by Default","Oulu","*Removed in Kona*","n/a" +"`p0209r2 `__","LWG","make_from_tuple: apply for construction","Oulu","|Complete|","3.9" +"`p0219r1 `__","LWG","Relative Paths for Filesystem","Oulu","|Complete|","7.0" +"`p0254r2 `__","LWG","Integrating std::string_view and std::string","Oulu","|Complete|","4.0" +"`p0258r2 `__","LWG","has_unique_object_representations","Oulu","|Complete|","6.0" +"`p0295r0 `__","LWG","Adopt Selected Library Fundamentals V2 Components for C++17","Oulu","|Complete|","4.0" +"`p0302r1 `__","LWG","Removing Allocator Support in std::function","Oulu","|Complete|","4.0" +"`p0307r2 `__","LWG","Making Optional Greater Equal Again","Oulu","|Complete|","4.0" +"`p0336r1 `__","LWG","Better Names for Parallel Execution Policies in C++17","Oulu","","" +"`p0337r0 `__","LWG","Delete ``operator=``\ for polymorphic_allocator","Oulu","|Complete|","3.9" +"`p0346r1 `__","LWG","A Nomenclature Tweak","Oulu","|Complete|","3.9" +"`p0358r1 `__","LWG","Fixes for not_fn","Oulu","|Complete|","3.9" +"`p0371r1 `__","LWG","Temporarily discourage memory_order_consume","Oulu","|Nothing To Do|","n/a" +"`p0392r0 `__","LWG","Adapting string_view by filesystem paths","Oulu","|Complete|","4.0" +"`p0393r3 `__","LWG","Making Variant Greater Equal","Oulu","|Complete|","4.0" +"`P0394r4 `__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","","" +"","","","","","" +"`P0003R5 `__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0" +"`P0067R5 `__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial| [#note-P0067]","" +"`P0403R1 `__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0" +"`P0414R2 `__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0" +"`P0418R2 `__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","","" +"`P0426R1 `__","LWG","Constexpr for ``std::char_traits``\ ","Issaquah","|Complete|","4.0" +"`P0435R1 `__","LWG","Resolving LWG Issues re ``common_type``\ ","Issaquah","|Complete|","4.0" +"`P0502R0 `__","LWG","Throwing out of a parallel algorithm terminates - but how?","Issaquah","","" +"`P0503R0 `__","LWG","Correcting library usage of ""literal type""","Issaquah","|Complete|","4.0" +"`P0504R0 `__","LWG","Revisiting in-place tag types for any/optional/variant","Issaquah","|Complete|","4.0" +"`P0505R0 `__","LWG","Wording for GB 50 - constexpr for chrono","Issaquah","|Complete|","4.0" +"`P0508R0 `__","LWG","Wording for GB 58 - structured bindings for node_handles","Issaquah","","" +"`P0509R1 `__","LWG","Updating ""Restrictions on exception handling""","Issaquah","|Nothing To Do|","n/a" +"`P0510R0 `__","LWG","Disallowing references, incomplete types, arrays, and empty variants","Issaquah","|Complete|","4.0" +"`P0513R0 `__","LWG","Poisoning the Hash","Issaquah","|Complete|","5.0" +"`P0516R0 `__","LWG","Clarify That shared_future's Copy Operations have Wide Contracts","Issaquah","|Complete|","4.0" +"`P0517R0 `__","LWG","Make future_error Constructible","Issaquah","|Complete|","4.0" +"`P0521R0 `__","LWG","Proposed Resolution for CA 14 (shared_ptr use_count/unique)","Issaquah","|Nothing To Do|","n/a" +"","","","","","" +"`P0156R2 `__","LWG","Variadic Lock guard(rev 5)","Kona","|Complete|","5.0" +"`P0270R3 `__","CWG","Removing C dependencies from signal handler wording","Kona","","" +"`P0298R3 `__","CWG","A byte type definition","Kona","|Complete|","5.0" +"`P0317R1 `__","LWG","Directory Entry Caching for Filesystem","Kona","|Complete|","7.0" +"`P0430R2 `__","LWG","File system library on non-POSIX-like operating systems","Kona","|Complete|","7.0" +"`P0433R2 `__","LWG","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","Kona","|Complete|","14.0" +"`P0452R1 `__","LWG","Unifying Parallel Algorithms","Kona","","" +"`P0467R2 `__","LWG","Iterator Concerns for Parallel Algorithms","Kona","","" +"`P0492R2 `__","LWG","Proposed Resolution of C++17 National Body Comments for Filesystems","Kona","|Complete|","7.0" +"`P0518R1 `__","LWG","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","Kona","","" +"`P0523R1 `__","LWG","Wording for CH 10: Complexity of parallel algorithms","Kona","","" +"`P0548R1 `__","LWG","common_type and duration","Kona","|Complete|","5.0" +"`P0558R1 `__","LWG","Resolving atomic named base class inconsistencies","Kona","|Complete|","" +"`P0574R1 `__","LWG","Algorithm Complexity Constraints and Parallel Overloads","Kona","","" +"`P0599R1 `__","LWG","noexcept for hash functions","Kona","|Complete|","5.0" +"`P0604R0 `__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|","" +"`P0607R0 `__","LWG","Inline Variables for the Standard Library","Kona","|In Progress| [#note-P0607]_","6.0" +"`P0618R0 `__","LWG","Deprecating ","Kona","","" +"`P0623R0 `__","LWG","Final C++17 Parallel Algorithms Fixes","Kona","","" +"","","","","","" +"`P0682R1 `__","LWG","Repairing elementary string conversions","Toronto","","" +"`P0739R0 `__","LWG","Some improvements to class template argument deduction integration into the standard library","Toronto","|Complete|","5.0" diff --git a/docs/Status/Cxx20.rst b/docs/Status/Cxx20.rst new file mode 100644 index 000000000..437440776 --- /dev/null +++ b/docs/Status/Cxx20.rst @@ -0,0 +1,58 @@ +.. _cxx20-status: + +================================ +libc++ C++20 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In July 2017, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++2a". +In September 2020, the C++ standard committee approved this draft, and sent it to ISO for approval as C++20. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx20: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx20Papers.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class] and |sect|\ [mem.poly.allocator.class]. + .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature. Not yet implemented LWG-issues will cause API and ABI breakage. + .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. + .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. + .. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. + + +.. _issues-status-cxx20: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx20Issues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/Cxx20Issues.csv b/docs/Status/Cxx20Issues.csv new file mode 100644 index 000000000..68e1c2730 --- /dev/null +++ b/docs/Status/Cxx20Issues.csv @@ -0,0 +1,300 @@ +"Issue #","Issue Name","Meeting","Status","First released version","Labels" +"`2070 `__","``allocate_shared``\ should use ``allocator_traits::construct``\ ","Toronto","Resolved by `P0674R1 `__","" +"`2444 `__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","","" +"`2593 `__","Moved-from state of Allocators","Toronto","","" +"`2597 `__","``std::log``\ misspecified for complex numbers","Toronto","","" +"`2783 `__","``stack::emplace()``\ and ``queue::emplace()``\ should return ``decltype(auto)``\ ","Toronto","|Complete|","" +"`2932 `__","Constraints on parallel algorithm implementations are underspecified","Toronto","","" +"`2937 `__","Is ``equivalent(""existing_thing"", ""not_existing_thing"")``\ an error","Toronto","|Complete|","" +"`2940 `__","``result_of``\ specification also needs a little cleanup","Toronto","","" +"`2942 `__","LWG 2873's resolution missed ``weak_ptr::owner_before``\ ","Toronto","|Complete|","" +"`2954 `__","Specialization of the convenience variable templates should be prohibited","Toronto","|Complete|","" +"`2961 `__","Bad postcondition for ``set_default_resource``\ ","Toronto","","" +"`2966 `__","Incomplete resolution of US 74","Toronto","|Nothing To Do|","" +"`2974 `__","Diagnose out of bounds ``tuple_element/variant_alternative``\ ","Toronto","|Complete|","" +"","","","","" +"`2779 `__","[networking.ts] Relax requirements on buffer sequence iterators","Albuquerque","","" +"`2870 `__","Default value of parameter theta of polar should be dependent","Albuquerque","|Complete|","" +"`2935 `__","What should create_directories do when p already exists but is not a directory?","Albuquerque","|Nothing To Do|","" +"`2941 `__","[thread.req.timing] wording should apply to both member and namespace-level functions","Albuquerque","|Nothing To Do|","" +"`2944 `__","LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception","Albuquerque","|Nothing To Do|","" +"`2945 `__","Order of template parameters in optional comparisons","Albuquerque","|Complete|","" +"`2948 `__","unique_ptr does not define operator<< for stream output","Albuquerque","|Complete|","" +"`2950 `__","std::byte operations are misspecified","Albuquerque","|Complete|","" +"`2952 `__","iterator_traits should work for pointers to cv T","Albuquerque","|Complete|","" +"`2953 `__","LWG 2853 should apply to deque::erase too","Albuquerque","|Complete|","" +"`2958 `__","Moves improperly defined as deleted","Albuquerque","|Complete|","" +"`2964 `__","Apparently redundant requirement for dynamic_pointer_cast","Albuquerque","","" +"`2965 `__","Non-existing path::native_string() in filesystem_error::what() specification","Albuquerque","|Nothing To Do|","" +"`2972 `__","What is ``is_trivially_destructible_v``\ ?","Albuquerque","|Complete|","" +"`2976 `__","Dangling uses_allocator specialization for packaged_task","Albuquerque","|Complete|","" +"`2977 `__","unordered_meow::merge() has incorrect Throws: clause","Albuquerque","|Nothing To Do|","" +"`2978 `__","Hash support for pmr::string and friends","Albuquerque","","" +"`2979 `__","aligned_union should require complete object types","Albuquerque","|Complete|","" +"`2980 `__","Cannot compare_exchange empty pointers","Albuquerque","","" +"`2981 `__","Remove redundant deduction guides from standard library","Albuquerque","|Nothing To Do|","" +"`2982 `__","Making size_type consistent in associative container deduction guides","Albuquerque","","" +"`2988 `__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0" +"`2993 `__","reference_wrapper conversion from T&&","Albuquerque","|Complete|","13.0" +"`2998 `__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|","" +"`3001 `__","weak_ptr::element_type needs remove_extent_t","Albuquerque","|Complete|","14.0" +"`3024 `__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|","" +"","","","","" +"`2164 `__","What are the semantics of ``vector.emplace(vector.begin(), vector.back())``\ ?","Jacksonville","|Complete|","" +"`2243 `__","``istream::putback``\ problem","Jacksonville","|Complete|","" +"`2816 `__","``resize_file``\ has impossible postcondition","Jacksonville","|Nothing To Do|","" +"`2843 `__","Unclear behavior of ``std::pmr::memory_resource::do_allocate()``\ ","Jacksonville","|Complete|","" +"`2849 `__","Why does ``!is_regular_file(from)``\ cause ``copy_file``\ to report a ""file already exists"" error?","Jacksonville","|Nothing To Do|","" +"`2851 `__","``std::filesystem``\ enum classes are now underspecified","Jacksonville","|Nothing To Do|","" +"`2946 `__","LWG 2758's resolution missed further corrections","Jacksonville","|Complete|","" +"`2969 `__","``polymorphic_allocator::construct()``\ shouldn't pass ``resource()``\ ","Jacksonville","|Complete|","" +"`2975 `__","Missing case for ``pair``\ construction in scoped and polymorphic allocators","Jacksonville","","" +"`2989 `__","``path``\ 's stream insertion operator lets you insert everything under the sun","Jacksonville","|Complete|","" +"`3000 `__","``monotonic_memory_resource::do_is_equal``\ uses ``dynamic_cast``\ unnecessarily","Jacksonville","","" +"`3002 `__","[networking.ts] ``basic_socket_acceptor::is_open()``\ isn't ``noexcept``\ ","Jacksonville","","" +"`3004 `__","|sect|\ [string.capacity] and |sect|\ [vector.capacity] should specify time complexity for ``capacity()``\ ","Jacksonville","|Nothing To Do|","" +"`3005 `__","Destruction order of arrays by ``make_shared/allocate_shared``\ only recommended?","Jacksonville","","" +"`3007 `__","``allocate_shared``\ should rebind allocator to *cv*-unqualified ``value_type``\ for construction","Jacksonville","","" +"`3009 `__","Including ````\ doesn't provide ``std::size/empty/data``\ ","Jacksonville","|Complete|","" +"`3010 `__","[networking.ts] ``uses_executor``\ says ""if a type ``T::executor_type``\ exists""","Jacksonville","","" +"`3013 `__","``(recursive_)directory_iterator``\ construction and traversal should not be ``noexcept``\ ","Jacksonville","|Complete|","" +"`3014 `__","More ``noexcept``\ issues with filesystem operations","Jacksonville","|Complete|","" +"`3015 `__","``copy_options::*unspecified*``\ underspecified","Jacksonville","|Nothing To Do|","" +"`3017 `__","``list splice``\ functions should use ``addressof``\ ","Jacksonville","|Complete|","" +"`3020 `__","[networking.ts] Remove spurious nested ``value_type``\ buffer sequence requirement","Jacksonville","","" +"`3026 `__","``filesystem::weakly_canonical``\ still defined in terms of ``canonical(p, base)``\ ","Jacksonville","|Complete|","" +"`3030 `__","Who shall meet the requirements of ``try_lock``\ ?","Jacksonville","|Nothing To Do|","" +"`3034 `__","P0767R1 breaks previously-standard-layout types","Jacksonville","|Complete|","" +"`3035 `__","``std::allocator``\ 's constructors should be ``constexpr``\ ","Jacksonville","|Complete|","" +"`3039 `__","Unnecessary ``decay``\ in ``thread``\ and ``packaged_task``\ ","Jacksonville","|Complete|","" +"`3041 `__","Unnecessary ``decay``\ in ``reference_wrapper``\ ","Jacksonville","|Complete|","" +"`3042 `__","``is_literal_type_v``\ should be inline","Jacksonville","|Complete|","" +"`3043 `__","Bogus postcondition for ``filesystem_error``\ constructor","Jacksonville","|Complete|","" +"`3045 `__","``atomic``\ doesn't have ``value_type``\ or ``difference_type``\ ","Jacksonville","","" +"`3048 `__","``transform_reduce(exec, first1, last1, first2, init)``\ discards execution policy","Jacksonville","","" +"`3051 `__","Floating point classifications were inadvertently changed in P0175","Jacksonville","|Nothing To Do|","" +"`3075 `__","``basic_string``\ needs deduction guides from ``basic_string_view``\ ","Jacksonville","|Complete|","" +"","","","","" +"`2139 `__","What is a user-defined type?","Rapperswil","","" +"`2970 `__","Return type of std::visit misspecified","Rapperswil","","" +"`3058 `__","Parallel adjacent_difference shouldn't require creating temporaries","Rapperswil","","" +"`3062 `__","Unnecessary decay_t in is_execution_policy_v should be remove_cvref_t","Rapperswil","","" +"`3067 `__","recursive_directory_iterator::pop must invalidate","Rapperswil","|Nothing To Do|","" +"`3071 `__","[networking.ts] read_until still refers to ""input sequence""","Rapperswil","|Nothing To Do|","" +"`3074 `__","Non-member functions for valarray should only deduce from the valarray","Rapperswil","","" +"`3076 `__","basic_string CTAD ambiguity","Rapperswil","|Complete|","" +"`3079 `__","LWG 2935 forgot to fix the existing_p overloads of create_directory","Rapperswil","|Nothing To Do|","" +"`3080 `__","Floating point from_chars pattern specification breaks round-tripping","Rapperswil","","" +"`3083 `__","What should ios::iword(-1) do?","Rapperswil","|Nothing To Do|","" +"`3094 `__","[time.duration.io]p4 makes surprising claims about encoding","Rapperswil","","" +"`3100 `__","Unnecessary and confusing ""empty span"" wording","Rapperswil","|Nothing To Do|","" +"`3102 `__","Clarify span iterator and ``const_iterator`` behavior","Rapperswil","|Complete|","" +"`3104 `__","Fixing duration division","Rapperswil","|Complete|","" +"","","","","" +"`2183 `__","Muddled allocator requirements for ``match_results``\ constructors","San Diego","|Complete|","" +"`2184 `__","Muddled allocator requirements for ``match_results``\ assignments","San Diego","|Complete|","" +"`2412 `__","``promise::set_value()``\ and ``promise::get_future()``\ should not race","San Diego","","" +"`2499 `__","``operator>>(basic_istream&, CharT*)``\ makes it hard to avoid buffer overflows","San Diego","Resolved by P0487R1","" +"`2682 `__","``filesystem::copy()``\ won't create a symlink to a directory","San Diego","|Nothing To Do|","" +"`2697 `__","[concurr.ts] Behavior of ``future/shared_future``\ unwrapping constructor when given an invalid ``future``\ ","San Diego","","" +"`2797 `__","Trait precondition violations","San Diego","Resolved by 1285R0","" +"`2936 `__","Path comparison is defined in terms of the generic format","San Diego","|Complete|","" +"`2943 `__","Problematic specification of the wide version of ``basic_filebuf::open``\ ","San Diego","|Nothing To Do|","" +"`2960 `__","[fund.ts.v3] ``nonesuch``\ is insufficiently useless","San Diego","|Complete|","" +"`2995 `__","``basic_stringbuf``\ default constructor forbids it from using SSO capacity","San Diego","","" +"`2996 `__","Missing rvalue overloads for ``shared_ptr``\ operations","San Diego","","" +"`3008 `__","``make_shared``\ (sub)object destruction semantics are not specified","San Diego","","" +"`3022 `__","``is_convertible``\ may lead to ODR","San Diego","Resolved by 1285R0","" +"`3025 `__","Map-like container deduction guides should use ``pair``\ , not ``pair``\ ","San Diego","|Complete|","" +"`3031 `__","Algorithms and predicates with non-const reference arguments","San Diego","","" +"`3037 `__","``polymorphic_allocator``\ and incomplete types","San Diego","","" +"`3038 `__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","|Complete|","14.0" +"`3054 `__","``uninitialized_copy``\ appears to not be able to meet its exception-safety guarantee","San Diego","","" +"`3065 `__","LWG 2989 missed that all ``path``\ 's other operators should be hidden friends as well","San Diego","|Complete|","" +"`3096 `__","``path::lexically_relative``\ is confused by trailing slashes","San Diego","|Complete|","" +"`3116 `__","``OUTERMOST_ALLOC_TRAITS``\ needs ``remove_reference_t``\ ","San Diego","","" +"`3122 `__","``__cpp_lib_chrono_udls``\ was accidentally dropped","San Diego","|Complete|","" +"`3127 `__","``basic_osyncstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","","" +"`3128 `__","``strstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","|Nothing To Do|","" +"`3129 `__","``regex_token_iterator``\ constructor uses wrong pointer arithmetic","San Diego","","" +"`3130 `__","|sect|\ [input.output] needs many ``addressof``\ ","San Diego","","" +"`3131 `__","``addressof``\ all the things","San Diego","","" +"`3132 `__","Library needs to ban macros named ``expects``\ or ``ensures``\ ","San Diego","|Nothing To Do|","" +"`3134 `__","[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961","San Diego","Resolved by P1210R0","" +"`3137 `__","Header for ``__cpp_lib_to_chars``\ ","San Diego","|Complete|","" +"`3145 `__","``file_clock``\ breaks ABI for C++17 implementations","San Diego","|Complete|","" +"`3147 `__","Definitions of ""likely"" and ""unlikely"" are likely to cause problems","San Diego","","" +"`3148 `__","````\ should be freestanding","San Diego","","" +"`3153 `__","``Common``\ and ``common_type``\ have too little in common","San Diego","|Complete|","13.0" +"`3154 `__","``Common``\ and ``CommonReference``\ have a common defect","San Diego","","" +"","","","","" +"`3012 `__","``atomic``\ is unimplementable for non-``is_trivially_copy_constructible T``\ ","Kona","","" +"`3040 `__","``basic_string_view::starts_with``\ *Effects* are incorrect","Kona","|Complete|","" +"`3077 `__","``(push|emplace)_back``\ should invalidate the ``end``\ iterator","Kona","|Nothing To Do|","" +"`3087 `__","One final ``&x``\ in |sect|\ [list.ops]","Kona","|Nothing To Do|","" +"`3101 `__","``span``\ 's ``Container``\ constructors need another constraint","Kona","|Complete|","" +"`3112 `__","``system_error``\ and ``filesystem_error``\ constructors taking a ``string``\ may not be able to meet their postconditions","Kona","","" +"`3119 `__","Program-definedness of closure types","Kona","|Nothing To Do|","" +"`3133 `__","Modernizing numeric type requirements","Kona","","" +"`3144 `__","``span``\ does not have a ``const_pointer``\ typedef","Kona","|Complete|","" +"`3173 `__","Enable CTAD for ``ref-view``\ ","Kona","","","|ranges|" +"`3179 `__","``subrange``\ should always model ``Range``\ ","Kona","","","|ranges|" +"`3180 `__","Inconsistently named return type for ``ranges::minmax_element``\ ","Kona","","","|ranges|" +"`3182 `__","Specification of ``Same``\ could be clearer","Kona","","" +"","","","","" +"`2899 `__","``is_(nothrow_)move_constructible``\ and ``tuple``\ , ``optional``\ and ``unique_ptr``\ ","Cologne","","" +"`3055 `__","``path::operator+=(*single-character*)``\ misspecified","Cologne","|Complete|","7.0" +"`3158 `__","``tuple(allocator_arg_t, const Alloc&)``\ should be conditionally explicit","Cologne","|Complete|","10.0" +"`3169 `__","``ranges``\ permutation generators discard useful information","Cologne","","","|ranges|" +"`3183 `__","Normative permission to specialize Ranges variable templates","Cologne","","","|ranges|" +"`3184 `__","Inconsistencies in ``bind_front``\ wording","Cologne","|Complete|","13.0" +"`3185 `__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","","" +"`3186 `__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","Cologne","","","|ranges|" +"`3187 `__","`P0591R4 `__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","Cologne","","" +"`3191 `__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","Cologne","","","|ranges|" +"`3196 `__","``std::optional``\ is ill-formed is ``T``\ is an array","Cologne","|Complete|","" +"`3198 `__","Bad constraint on ``std::span::span()``\ ","Cologne","|Complete|","" +"`3199 `__","``istream >> bitset<0>``\ fails","Cologne","","" +"`3202 `__","P0318R1 was supposed to be revised","Cologne","|Complete|","" +"`3206 `__","``year_month_day``\ conversion to ``sys_days``\ uses not-existing member function","Cologne","|Complete|","" +"`3208 `__","``Boolean``\ 's expression requirements are ordered inconsistently","Cologne","|Nothing To Do|","" +"`3209 `__","Expression in ``year::ok()``\ returns clause is ill-formed","Cologne","|Complete|","" +"","","","","" +"`3231 `__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|","" +"`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","","|chrono|" +"`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","14.0" +"`3218 `__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","","|chrono| |format|" +"`3224 `__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","","","|chrono|" +"`3230 `__","Format specifier ``%y/%Y``\ is missing locale alternative versions","Belfast","","","|chrono| |format|" +"`3232 `__","Inconsistency in ``zoned_time``\ deduction guides","Belfast","","","|chrono|" +"`3222 `__","P0574R1 introduced preconditions on non-existent parameters","Belfast","","" +"`3221 `__","Result of ``year_month``\ arithmetic with ``months``\ is ambiguous","Belfast","|Complete|","8.0" +"`3235 `__","``parse``\ manipulator without abbreviation is not callable","Belfast","","" +"`3246 `__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","","","|format|" +"`3253 `__","``basic_syncbuf::basic_syncbuf()``\ should not be explicit","Belfast","","" +"`3245 `__","Unnecessary restriction on ``'%p'``\ parse specifier","Belfast","","","|chrono|" +"`3244 `__","Constraints for ``Source``\ in |sect|\ [fs.path.req] insufficiently constrainty","Belfast","","" +"`3241 `__","``chrono-spec``\ grammar ambiguity in |sect|\ [time.format]","Belfast","","","|chrono| |format|" +"`3257 `__","Missing feature testing macro update from P0858","Belfast","","" +"`3256 `__","Feature testing macro for ``constexpr``\ algorithms","Belfast","|Complete|","13.0" +"`3273 `__","Specify ``weekday_indexed``\ to range of ``[0, 7]``\ ","Belfast","","","|chrono|" +"`3070 `__","``path::lexically_relative``\ causes surprising results if a filename can also be a *root-name*","Belfast","","" +"`3266 `__","``to_chars(bool)``\ should be deleted","Belfast","|Complete|","14.0" +"`3272 `__","``%I%p``\ should parse/format ``duration``\ since midnight","Belfast","","","|chrono| |format|" +"`3259 `__","The definition of *constexpr iterators* should be adjusted","Belfast","","","|ranges|" +"`3103 `__","Errors in taking subview of ``span``\ should be ill-formed where possible","Belfast","","" +"`3274 `__","Missing feature test macro for ````\ ","Belfast","|Complete|","11.0" +"`3276 `__","Class ``split_view::outer_iterator::value_type``\ should inherit from ``view_interface``\ ","Belfast","","","|ranges|" +"`3277 `__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","","","|ranges|" +"`3149 `__","``DefaultConstructible``\ should require default initialization","Belfast","|Complete|","13.0" +"","","","","" +"`1203 `__","More useful rvalue stream insertion","Prague","|Complete|","12.0" +"`2859 `__","Definition of *reachable* in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object","Prague","","" +"`3018 `__","``shared_ptr``\ of function type","Prague","","" +"`3050 `__","Conversion specification problem in ``chrono::duration``\ constructor","Prague","","","|chrono|" +"`3141 `__","``CopyConstructible``\ doesn't preserve source values","Prague","|Nothing to do|","" +"`3150 `__","``UniformRandomBitGenerator``\ should validate ``min``\ and ``max``\ ","Prague","|Complete|","13.0" +"`3175 `__","The ``CommonReference``\ requirement of concept ``SwappableWith``\ is not satisfied in the example","Prague","|Complete|","13.0" +"`3194 `__","``ConvertibleTo``\ prose does not match code","Prague","|Complete|","13.0" +"`3200 `__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|","" +"`3201 `__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|","" +"`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","","","|chrono|" +"`3233 `__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","","" +"`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","14.0" +"`3238 `__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","","" +"`3242 `__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","|Complete|","Clang 14","|format|" +"`3243 `__","``std::format``\ and negative zeroes","Prague","|Complete|","14.0","|format|" +"`3247 `__","``ranges::iter_move``\ should perform ADL-only lookup of ``iter_move``\ ","Prague","","","|ranges|" +"`3248 `__","``std::format``\ ``#b``\ , ``#B``\ , ``#o``\ , ``#x``\ , and ``#X``\ presentation types misformat negative numbers","Prague","|Complete|","14.0","|format|" +"`3250 `__","``std::format``\ : ``#``\ (alternate form) for NaN and inf","Prague","|Complete|","14.0","|format|" +"`3251 `__","Are ``std::format``\ alignment specifiers applied to string arguments?","Prague","|Complete|","14.0","|format|" +"`3252 `__","Parse locale's aware modifiers for commands are not consistent with POSIX spec","Prague","","","|chrono|" +"`3254 `__","Strike ``stop_token``\ 's ``operator!=``\ ","Prague","","" +"`3255 `__","``span``\ 's ``array``\ constructor is too strict","Prague","|Complete|","" +"`3260 `__","``year_month*``\ arithmetic rejects durations convertible to years","Prague","","","|chrono|" +"`3262 `__","Formatting of negative durations is not specified","Prague","","","|chrono| |format|" +"`3264 `__","``sized_range``\ and ``ranges::size``\ redundantly use ``disable_sized_range``\ ","Prague","","","|ranges|" +"`3269 `__","Parse manipulators do not specify the result of the extraction from stream","Prague","","","|chrono|" +"`3270 `__","Parsing and formatting ``%j``\ with ``duration``\ s","Prague","","","|chrono| |format|" +"`3280 `__","View converting constructors can cause constraint recursion and are unneeded","Prague","","","|ranges|" +"`3281 `__","Conversion from ``*pair-like*``\ types to ``subrange``\ is a silent semantic promotion","Prague","","","|ranges|" +"`3282 `__","``subrange``\ converting constructor should disallow derived to base conversions","Prague","","","|ranges|" +"`3284 `__","``random_access_iterator``\ semantic constraints accidentally promote difference type using unary negate","Prague","","","|ranges|" +"`3285 `__","The type of a customization point object shall satisfy ``semiregular``\ ","Prague","","" +"`3286 `__","``ranges::size``\ is not required to be valid after a call to ``ranges::begin``\ on an input range","Prague","","","|ranges|" +"`3291 `__","``iota_view::iterator``\ has the wrong ``iterator_category``\ ","Prague","","","|ranges|" +"`3292 `__","``iota_view``\ is under-constrained","Prague","","","|ranges|" +"`3294 `__","``zoned_time``\ deduction guides misinterprets ``string``\ /``char*``\ ","Prague","","","|chrono|" +"`3296 `__","Inconsistent default argument for ``basic_regex<>::assign``\ ","Prague","|Complete|","" +"`3299 `__","Pointers don't need customized iterator behavior","Prague","","","|ranges|" +"`3300 `__","Non-array ``ssize``\ overload is underconstrained","Prague","","" +"`3301 `__","``transform_view::iterator``\ has incorrect ``iterator_category``\ ","Prague","","","|ranges|" +"`3302 `__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","","","|ranges|" +"`3303 `__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","","" +"`3304 `__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","","" +"`3307 `__","``std::allocator().allocate(n)``\ ","Prague","","" +"`3310 `__","Replace ``SIZE_MAX``\ with ``numeric_limits::max()``\ ","Prague","","" +"`3313 `__","``join_view::iterator::operator--``\ is incorrectly constrained","Prague","","","|ranges|" +"`3314 `__","Is stream insertion behavior locale dependent when ``Period::type``\ is ``micro``\ ?","Prague","","","|chrono|" +"`3315 `__","Correct Allocator Default Behavior","Prague","","" +"`3316 `__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","","|chrono|" +"`3317 `__","Incorrect ``operator<<``\ for floating-point durations","Prague","","","|chrono|" +"`3318 `__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|" +"`3319 `__","Properly reference specification of IANA time zone database","Prague","","","|chrono|" +"`3320 `__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|","" +"`3321 `__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","","" +"`3323 `__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","","|ranges|" +"`3324 `__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","|Complete|","14.0","|spaceship|" +"`3325 `__","Constrain return type of transformation function for ``transform_view``\ ","Prague","","","|ranges|" +"`3326 `__","``enable_view``\ has false positives","Prague","|In progress|","","|ranges|" +"`3327 `__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|","","|format|" +"`3328 `__","Clarify that ``std::string``\ is not good for UTF-8","Prague","","" +"`3329 `__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0" +"`3330 `__","Include ````\ from most library headers","Prague","|Complete|","13.0","|spaceship|" +"`3331 `__","Define ``totally_ordered/_with``\ in terms of ``partially-ordered-with``\ ","Prague","|Complete|","13.0" +"`3332 `__","Issue in |sect|\ [time.format]","Prague","","","|chrono| |format|" +"`3334 `__","``basic_osyncstream``\ move assignment and destruction calls ``basic_syncbuf::emit()``\ twice","Prague","","" +"`3335 `__","Resolve C++20 NB comments US 273 and GB 274","Prague","","","|ranges|" +"`3338 `__","Rename ``default_constructible``\ to ``default_initializable``\ ","Prague","|Complete|","13.0" +"`3340 `__","Formatting functions should throw on argument/format string mismatch in |sect|\ [format.functions]","Prague","|Complete|","14.0","|format|" +"`3346 `__","``pair``\ and ``tuple``\ copy and move constructor have backwards specification","Prague","","" +"`3347 `__","``std::pair``\ now requires ``T``\ and ``U``\ to be less-than-comparable","Prague","","" +"`3348 `__","``__cpp_lib_unwrap_ref``\ in wrong header","Prague","|Complete|","12.0" +"`3349 `__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","","" +"`3350 `__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","","","|spaceship|" +"`3351 `__","``ranges::enable_safe_range``\ should not be constrained","Prague","","","|ranges|" +"`3352 `__","``strong_equality``\ isn't a thing","Prague","|Nothing To Do|","","|spaceship|" +"`3354 `__","``has_strong_structural_equality``\ has a meaningless definition","Prague","","","|spaceship|" +"`3355 `__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","","","|ranges|" +"`3356 `__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","|Complete|","12.0" +"`3358 `__","|sect|\ [span.cons] is mistaken that ``to_address``\ can throw","Prague","","" +"`3359 `__","````\ leap second support should allow for negative leap seconds","Prague","","","|chrono|" +"`3360 `__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","|Nothing To Do|","","|spaceship|" +"`3362 `__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","","" +"`3363 `__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","","","|ranges|" +"`3364 `__","Initialize data members of ranges and their iterators","Prague","","","|ranges|" +"`3367 `__","Integer-class conversions should not throw","Prague","","" +"`3369 `__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","|Complete|","14.0" +"`3371 `__","``visit_format_arg``\ and ``make_format_args``\ are not hidden friends","Prague","|Complete|","14.0","|format|" +"`3372 `__","``vformat_to``\ should not try to deduce ``Out``\ twice","Prague","|Complete|","14.0","|format|" +"`3373 `__","``{to,from}_chars_result``\ and ``format_to_n_result``\ need the ""we really mean what we say"" wording","Prague","|Complete|","14.0","|format|" +"`3374 `__","P0653 + P1006 should have made the other ``std::to_address``\ overload ``constexpr``\ ","Prague","|Complete|","12.0" +"`3375 `__","``decay``\ in ``viewable_range``\ should be ``remove_cvref``\ ","Prague","","","|ranges|" +"`3377 `__","``elements_view::iterator``\ befriends a specialization of itself","Prague","","","|ranges|" +"`3379 `__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|","" +"`3380 `__","``common_type``\ and comparison categories","Prague","","","|spaceship|" +"`3381 `__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","","","|ranges|" +"`3382 `__","NTTP for ``pair``\ and ``array``\ ","Prague","","" +"`3383 `__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","","","|chrono|" +"`3384 `__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","","","|ranges|" +"`3385 `__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","","","|ranges|" +"`3387 `__","|sect|\ [range.reverse.view] ``reverse_view``\ unintentionally requires ``range``\ ","Prague","","","|ranges|" +"`3388 `__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","","","|ranges|" +"`3389 `__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","","","|ranges|" +"`3390 `__","``make_move_iterator()``\ cannot be used to construct a ``move_iterator``\ for a move-only iterator","Prague","|Complete|","14.0","|ranges|" +"`3393 `__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0" +"`3395 `__","Definition for three-way comparison needs to be updated (US 152)","Prague","","","|spaceship|" +"`3396 `__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","","" +"`3397 `__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","","","|ranges|" +"`3398 `__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","|Complete|","14.0","|ranges|" +"`3446 `__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0" diff --git a/docs/Status/Cxx20Papers.csv b/docs/Status/Cxx20Papers.csv new file mode 100644 index 000000000..cf983a4b4 --- /dev/null +++ b/docs/Status/Cxx20Papers.csv @@ -0,0 +1,207 @@ +"Paper #","Group","Paper Name","Meeting","Status","First released version" +"`P0463R1 `__","LWG","Endian just Endian","Toronto","|Complete|","7.0" +"`P0674R1 `__","LWG","Extending make_shared to Support Arrays","Toronto","","" +"","","","","","" +"`P0020R6 `__","LWG","Floating Point Atomic","Albuquerque","","" +"`P0053R7 `__","LWG","C++ Synchronized Buffered Ostream","Albuquerque","","" +"`P0202R3 `__","LWG","Add constexpr modifiers to functions in and Headers","Albuquerque","|Complete|","12.0" +"`P0415R1 `__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|In Progress|","7.0" +"`P0439R0 `__","LWG","Make ``std::memory_order``\ a scoped enumeration","Albuquerque","|Complete|","" +"`P0457R2 `__","LWG","String Prefix and Suffix Checking","Albuquerque","|Complete|","6.0" +"`P0550R2 `__","LWG","Transformation Trait ``remove_cvref``\ ","Albuquerque","|Complete|","6.0" +"`P0600R1 `__","LWG","nodiscard in the Library","Albuquerque","|In Progress| [#note-P0600]_","7.0" +"`P0616R0 `__","LWG","de-pessimize legacy algorithms with std::move","Albuquerque","|Complete|","12.0" +"`P0653R2 `__","LWG","Utility to convert a pointer to a raw pointer","Albuquerque","|Complete|","6.0" +"`P0718R2 `__","LWG","Atomic shared_ptr","Albuquerque","","" +"`P0767R1 `__","CWG","Deprecate POD","Albuquerque","|Complete|","7.0" +"`P0768R1 `__","CWG","Library Support for the Spaceship (Comparison) Operator","Albuquerque","|Complete|","" +"`P0777R1 `__","LWG","Treating Unnecessary ``decay``\ ","Albuquerque","|Complete|","7.0" +"`P0122R7 `__","LWG","","Jacksonville","|Complete|","7.0" +"`P0355R7 `__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|In Progress|","" +"`P0551R3 `__","LWG","Thou Shalt Not Specialize ``std``\ Function Templates!","Jacksonville","|Complete|","11.0" +"`P0753R2 `__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","","" +"`P0754R2 `__","LWG","","Jacksonville","|Complete|","7.0" +"`P0809R0 `__","LWG","Comparing Unordered Containers","Jacksonville","|Nothing To Do|","" +"`P0858R0 `__","LWG","Constexpr iterator requirements","Jacksonville","|Complete|","12.0" +"`P0905R1 `__","CWG","Symmetry for spaceship","Jacksonville","","" +"`P0966R1 `__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0" +"","","","","","" +"`P0019R8 `__","LWG","Atomic Ref","Rapperswil","","" +"`P0458R2 `__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0" +"`P0475R1 `__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|","" +"`P0476R2 `__","LWG","Bit-casting object representations","Rapperswil","|Complete|","14.0" +"`P0528R3 `__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","","" +"`P0542R5 `__","CWG","Support for contract based programming in C++","Rapperswil","*Removed in Cologne*","n/a" +"`P0556R3 `__","LWG","Integral power-of-2 operations","Rapperswil","|Complete|","9.0" +"`P0619R4 `__","LWG","Reviewing Deprecated Facilities of C++17 for C++20","Rapperswil","|Partial| [#note-P0619]_","" +"`P0646R1 `__","LWG","Improving the Return Value of Erase-Like Algorithms","Rapperswil","|Complete|","10.0" +"`P0722R3 `__","CWG","Efficient sized delete for variable sized classes","Rapperswil","|Complete|","9.0" +"`P0758R1 `__","LWG","Implicit conversion traits and utility functions","Rapperswil","|Complete|","" +"`P0759R1 `__","LWG","fpos Requirements","Rapperswil","|Complete|","11.0" +"`P0769R2 `__","LWG","Add shift to ","Rapperswil","|Complete|","12.0" +"`P0788R3 `__","LWG","Standard Library Specification in a Concepts and Contracts World","Rapperswil","*Removed in Cologne*","n/a" +"`P0879R0 `__","LWG","Constexpr for swap and swap related functions Also resolves LWG issue 2800.","Rapperswil","|Complete|","13.0" +"`P0887R1 `__","LWG","The identity metafunction","Rapperswil","|Complete|","8.0" +"`P0892R2 `__","CWG","explicit(bool)","Rapperswil","","" +"`P0898R3 `__","LWG","Standard Library Concepts","Rapperswil","|Complete|","13.0" +"`P0935R0 `__","LWG","Eradicating unnecessarily explicit default constructors from the standard library","Rapperswil","|Complete|","12.0" +"`P0941R2 `__","CWG","Integrating feature-test macros into the C++ WD","Rapperswil","|In Progress|","" +"`P1023R0 `__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0" +"`P1025R1 `__","CWG","Update The Reference To The Unicode Standard","Rapperswil","","" +"`P1120R0 `__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","","" +"","","","","","" +"`P0318R1 `__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0" +"`P0356R5 `__","LWG","Simplified partial function application","San Diego","|Complete|","13.0" +"`P0357R3 `__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0" +"`P0482R6 `__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|","" +"`P0487R1 `__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\ (LWG 2499)","San Diego","|Complete|","8.0" +"`P0591R4 `__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *","" +"`P0595R2 `__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0" +"`P0602R4 `__","LWG","variant and optional should propagate copy/move triviality","San Diego","|Complete|","8.0" +"`P0608R3 `__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0" +"`P0655R1 `__","LWG","visit: Explicit Return Type for visit","San Diego","|Complete|","12.0" +"`P0771R1 `__","LWG","std::function move constructor should be noexcept","San Diego","|Complete|","6.0" +"`P0896R4 `__","LWG","The One Ranges Proposal","San Diego","|In Progress|","" +"`P0899R1 `__","LWG","P0899R1 - LWG 3016 is not a defect","San Diego","|Nothing To Do|","" +"`P0919R3 `__","LWG","Heterogeneous lookup for unordered containers","San Diego","|Complete|","12.0" +"`P0972R0 `__","LWG"," ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","San Diego","|Complete|","8.0" +"`P1006R1 `__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0" +"`P1007R3 `__","LWG","``std::assume_aligned``\ ","San Diego","* *","" +"`P1020R1 `__","LWG","Smart pointer creation with default initialization","San Diego","* *","" +"`P1032R1 `__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0" +"`P1085R2 `__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0" +"`P1123R0 `__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *","" +"`P1148R0 `__","LWG","Cleaning up Clause 20","San Diego","* *","" +"`P1165R1 `__","LWG","Make stateful allocator propagation more consistent for ``operator+(basic_string)``\ ","San Diego","* *","" +"`P1209R0 `__","LWG","Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20","San Diego","|Complete|","8.0" +"`P1210R0 `__","LWG","Completing the Rebase of Library Fundamentals, Version 3, Working Draft","San Diego","* *","" +"`P1236R1 `__","CWG","Alternative Wording for P0907R4 Signed Integers are Two's Complement","San Diego","* *","" +"`P1248R1 `__","LWG","Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)","San Diego","|Complete|","13.0" +"`P1285R0 `__","LWG","Improving Completeness Requirements for Type Traits","San Diego","* *","" +"`P1353R0 `__","CWG","Missing feature test macros","San Diego","* *","" +"","","","","","" +"`P0339R6 `__","LWG","polymorphic_allocator<> as a vocabulary type","Kona","","" +"`P0340R3 `__","LWG","Making std::underlying_type SFINAE-friendly","Kona","|Complete|","9.0" +"`P0738R2 `__","LWG","I Stream, You Stream, We All Stream for istream_iterator","Kona","","" +"`P0811R3 `__","LWG","Well-behaved interpolation for numbers and pointers","Kona","|Complete|","9.0" +"`P0920R2 `__","LWG","Precalculated hash values in lookup","Kona","Reverted by `P1661 `__","" +"`P1001R2 `__","LWG","Target Vectorization Policies from Parallelism V2 TS to C++20","Kona","","" +"`P1024R3 `__","LWG","Usability Enhancements for std::span","Kona","|Complete|","9.0" +"`P1164R1 `__","LWG","Make create_directory() Intuitive","Kona","|Complete|","12.0" +"`P1227R2 `__","LWG","Signed ssize() functions, unsigned size() functions","Kona","|Complete|","9.0" +"`P1252R2 `__","LWG","Ranges Design Cleanup","Kona","","" +"`P1286R2 `__","CWG","Contra CWG DR1778","Kona","","" +"`P1357R1 `__","LWG","Traits for [Un]bounded Arrays","Kona","|Complete|","9.0" +"`P1458R1 `__","LWG","Mandating the Standard Library: Clause 16 - Language support library","Kona","|Complete|","9.0" +"`P1459R1 `__","LWG","Mandating the Standard Library: Clause 18 - Diagnostics library","Kona","|Complete|","9.0" +"`P1462R1 `__","LWG","Mandating the Standard Library: Clause 20 - Strings library","Kona","|Complete|","9.0" +"`P1463R1 `__","LWG","Mandating the Standard Library: Clause 21 - Containers library","Kona","","" +"`P1464R1 `__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0" +"","","","","","" +"`P0325R4 `__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0" +"`P0408R7 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","","" +"`P0466R5 `__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","","" +"`P0553R4 `__","LWG","Bit operations","Cologne","|Complete|","9.0" +"`P0631R8 `__","LWG","Math Constants","Cologne","|Complete|","11.0" +"`P0645R10 `__","LWG","Text Formatting","Cologne","|Complete| [#note-P0645]_","14.0" +"`P0660R10 `__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","","" +"`P0784R7 `__","CWG","More constexpr containers","Cologne","|Complete|","12.0" +"`P0980R1 `__","LWG","Making std::string constexpr","Cologne","","" +"`P1004R2 `__","LWG","Making std::vector constexpr","Cologne","","" +"`P1035R7 `__","LWG","Input Range Adaptors","Cologne","","" +"`P1065R2 `__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0" +"`P1135R6 `__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0" +"`P1207R4 `__","LWG","Movability of Single-pass Iterators","Cologne","","" +"`P1208R6 `__","LWG","Adopt source_location for C++20","Cologne","","" +"`P1355R2 `__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0" +"`P1361R2 `__","LWG","Integration of chrono with text formatting","Cologne","","" +"`P1423R3 `__","LWG","char8_t backward compatibility remediation","Cologne","|In Progress|","" +"`P1424R1 `__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 `__","" +"`P1466R3 `__","LWG","Miscellaneous minor fixes for chrono","Cologne","","" +"`P1474R1 `__","LWG","Helpful pointers for ContiguousIterator","Cologne","","" +"`P1502R1 `__","LWG","Standard library header units for C++20","Cologne","","" +"`P1522R1 `__","LWG","Iterator Difference Type and Integer Overflow","Cologne","","" +"`P1523R1 `__","LWG","Views and Size Types","Cologne","","" +"`P1612R1 `__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0" +"`P1614R2 `__","LWG","The Mothership has Landed","Cologne","|In Progress|","" +"`P1638R1 `__","LWG","basic_istream_view::iterator should not be copyable","Cologne","","" +"`P1643R1 `__","LWG","Add wait/notify to atomic_ref","Cologne","","" +"`P1644R0 `__","LWG","Add wait/notify to atomic","Cologne","","" +"`P1650R0 `__","LWG","Output std::chrono::days with 'd' suffix","Cologne","","" +"`P1651R0 `__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0" +"`P1652R1 `__","LWG","Printf corner cases in std::format","Cologne","|Complete|","14.0" +"`P1661R1 `__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|","" +"`P1754R1 `__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|","" +"","","","","","" +"`P0883R2 `__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883]_","14.0" +"`P1391R4 `__","LWG","Range constructor for std::string_view","Belfast","|Complete|","14.0" +"`P1394R4 `__","LWG","Range constructor for std::span","Belfast","|Complete|","14.0" +"`P1456R1 `__","LWG","Move-only views","Belfast","* *","" +"`P1622R3 `__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *","" +"`P1645R1 `__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0" +"`P1686R2 `__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *","" +"`P1690R1 `__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0" +"`P1716R3 `__","LWG","ranges compare algorithm are over-constrained","Belfast","* *","" +"`P1718R2 `__","LWG","Mandating the Standard Library: Clause 25 - Algorithms library","Belfast","* *","" +"`P1719R2 `__","LWG","Mandating the Standard Library: Clause 26 - Numerics library","Belfast","* *","" +"`P1720R2 `__","LWG","Mandating the Standard Library: Clause 28 - Localization library","Belfast","* *","" +"`P1721R2 `__","LWG","Mandating the Standard Library: Clause 29 - Input/Output library","Belfast","* *","" +"`P1722R2 `__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *","" +"`P1723R2 `__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *","" +"`P1855R0 `__","LWG","Make ````\ freestanding","Belfast","* *","" +"`P1862R1 `__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *","" +"`P1865R1 `__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0" +"`P1869R1 `__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *","" +"`P1870R1 `__","LWG","forwarding-range is too subtle","Belfast","|In Progress|","" +"`P1871R1 `__","LWG","Should concepts be enabled or disabled?","Belfast","|Complete|","14.0" +"`P1872R0 `__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0" +"`P1878R1 `__","LWG","Constraining Readable Types","Belfast","* *","" +"`P1892R1 `__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","|Complete|","14.0" +"`P1902R1 `__","LWG","Missing feature-test macros 2018-2019","Belfast","* *","" +"`P1959R0 `__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","* *","" +"`P1960R0 `__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *","" +"`P1961R0 `__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *","" +"`P1965R0 `__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *","" +"","","","","","" +"`P0586R2 `__","LWG","Safe integral comparisons","Prague","|Complete|","13.0" +"`P0593R6 `__","CWG","Implicit creation of objects for low-level object manipulation","Prague","* *","" +"`P1115R3 `__","LWG","Improving the Return Value of Erase-Like Algorithms II: Free erase/erase if","Prague","|Complete|","11.0" +"`P1243R4 `__","LWG","Rangify New Algorithms","Prague","* *","" +"`P1460R1 `__","LWG","Mandating the Standard Library: Clause 20 - Utilities library","Prague","* *","" +"`P1739R4 `__","LWG","Avoid template bloat for safe_ranges in combination with ""subrange-y"" view adaptors","Prague","* *","" +"`P1831R1 `__","LWG","Deprecating volatile: library","Prague","* *","" +"`P1868R2 `__","LWG","width: clarifying units of width and precision in std::format","Prague","|Complete|","14.0" +"`P1908R1 `__","CWG","Reserving Attribute Namespaces for Future Use","Prague","* *","" +"`P1937R2 `__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *","" +"`P1956R1 `__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0" +"`P1957R2 `__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *","" +"`P1963R0 `__","LWG","Fixing US 313","Prague","* *","" +"`P1964R2 `__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0" +"`P1970R2 `__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","* *","" +"`P1973R1 `__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","* *","" +"`P1976R2 `__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0" +"`P1981R0 `__","LWG","Rename leap to leap_second","Prague","* *","" +"`P1982R0 `__","LWG","Rename link to time_zone_link","Prague","* *","" +"`P1983R0 `__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","* *","" +"`P1994R1 `__","LWG","elements_view needs its own sentinel","Prague","* *","" +"`P2002R1 `__","CWG","Defaulted comparison specification cleanups","Prague","* *","" +"`P2045R1 `__","LWG","Missing Mandates for the standard library","Prague","* *","" +"`P2085R0 `__","CWG","Consistent defaulted comparisons","Prague","* *","" +"`P2091R0 `__","LWG","Issues with range access CPOs","Prague","* *","" +"`P2101R0 `__","LWG","'Models' subsumes 'satisfies' (Wording for US298 and US300)","Prague","* *","" +"`P2102R0 `__","LWG","Make 'implicit expression variations' more explicit (Wording for US185)","Prague","* *","" +"`P2106R0 `__","LWG","Alternative wording for GB315 and GB316","Prague","* *","" +"`P2116R0 `__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0" +"","","","","","" +"`P2231R1 `__","LWG","Missing constexpr in std::optional and std::variant","June 2021","|In progress|","13.0" +"`P2325R3 `__","LWG","Views should not be required to be default constructible","June 2021","|In progress|","" +"`P2210R2 `__","LWG",Superior String Splitting,"June 2021","","" +"`P2216R3 `__","LWG",std::format improvements,"June 2021","|Partial|","" +"`P2281R1 `__","LWG",Clarifying range adaptor objects,"June 2021","|Complete|","14.0" +"`P2328R1 `__","LWG",join_view should join all views of ranges,"June 2021","","" +"`P2367R0 `__","LWG",Remove misuses of list-initialization from Clause 24,"June 2021","","" +"","","","","","" +"`P2372R3 `__","LWG","Fixing locale handling in chrono formatters","October 2021","","" +"`P2415R2 `__","LWG","What is a ``view``","October 2021","|Complete|","14.0" +"`P2418R2 `__","LWG","Add support for ``std::generator``-like types to ``std::format``","October 2021","","" +"`P2432R1 `__","LWG","Fix ``istream_view``","October 2021","","" diff --git a/docs/Status/Cxx2b.rst b/docs/Status/Cxx2b.rst new file mode 100644 index 000000000..de8916293 --- /dev/null +++ b/docs/Status/Cxx2b.rst @@ -0,0 +1,48 @@ +.. _cxx2b-status: + +================================ +libc++ C++2b Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In November 2020, the C++ standard committee adopted the first changes to the next version of the C++ standard, known here as "C++2b" (probably to be C++23). + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx2b: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx2bPapers.csv + :header-rows: 1 + :widths: auto + +.. _issues-status-cxx2b: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx2bIssues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/Cxx2bIssues.csv b/docs/Status/Cxx2bIssues.csv new file mode 100644 index 000000000..bcbfe4402 --- /dev/null +++ b/docs/Status/Cxx2bIssues.csv @@ -0,0 +1,141 @@ +"Issue #","Issue Name","Meeting","Status","First released version","Labels" +"`2839 `__","Self-move-assignment of library types, again","November 2020","|Nothing To Do|","" +"`3117 `__","Missing ``packaged_task`` deduction guides","November 2020","","" +"`3143 `__","``monotonic_buffer_resource`` growth policy is unclear","November 2020","","" +"`3195 `__","What is the stored pointer value of an empty ``weak_ptr``?","November 2020","|Nothing To Do|","" +"`3211 `__","``std::tuple<>`` should be trivially constructible","November 2020","|Complete|","9.0" +"`3236 `__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","|Nothing To Do|","","|ranges|" +"`3265 `__","``move_iterator``'s conversions are more broken after P1207","November 2020","Fixed by `LWG3435 `__","" +"`3435 `__","``three_way_comparable_with, reverse_iterator>``","November 2020","|Complete|","13.0" +"`3432 `__","Missing requirement for ``comparison_category``","November 2020","","","|spaceship|" +"`3447 `__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","|Complete|","14.0" +"`3450 `__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","","","|ranges|" +"`3464 `__","``istream::gcount()`` can overflow","November 2020","","" +"`2731 `__","Existence of ``lock_guard::mutex_type`` typedef unclear","November 2020","|Complete|","5.0" +"`2743 `__","P0083R3 ``node_handle`` private members missing ""exposition only"" comment","November 2020","|Nothing To Do|","" +"`2820 `__","Clarify ```` macros","November 2020","|Nothing To Do|","" +"`3120 `__","Unclear behavior of ``monotonic_buffer_resource::release()``","November 2020","","" +"`3170 `__","``is_always_equal`` added to ``std::allocator`` makes the standard library treat derived types as always equal","November 2020","","" +"`3036 `__","``polymorphic_allocator::destroy`` is extraneous","November 2020","","" +"`3171 `__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","|Complete|","14.0" +"`3306 `__","``ranges::advance`` violates its preconditions","November 2020","|Complete|","14.0","|ranges|" +"`3403 `__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","","","|ranges|" +"`3404 `__","Finish removing subrange's conversions from pair-like","November 2020","","","|ranges|" +"`3405 `__","``common_view``'s converting constructor is bad, too","November 2020","|Complete|","14.0","|ranges|" +"`3406 `__","``elements_view::begin()`` and ``elements_view::end()`` have incompatible constraints","November 2020","","","|ranges|" +"`3419 `__","[algorithms.requirements]/15 doesn't reserve as many rights as it intends to","November 2020","|Nothing To Do|","" +"`3420 `__","cpp17-iterator should check that the type looks like an iterator first","November 2020","|Complete|","14.0","|ranges|" +"`3421 `__","Imperfect ADL emulation for boolean-testable","November 2020","|Nothing To Do|","","|ranges|" +"`3425 `__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","|Nothing To Do|","" +"`3426 `__","``operator<=>(const unique_ptr&, nullptr_t)`` can't get no satisfaction","November 2020","","","|spaceship|" +"`3427 `__","``operator<=>(const shared_ptr&, nullptr_t)`` definition ill-formed","November 2020","","","|spaceship|" +"`3428 `__","``single_view``'s in place constructor should be explicit","November 2020","|Complete|","14.0","|ranges|" +"`3434 `__","``ios_base`` never reclaims memory for iarray and parray","November 2020","|Nothing To Do|","" +"`3437 `__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","|Complete|","14.0" +"`3446 `__","``indirectly_readable_traits`` ambiguity for types with both ``value_type`` and ``element_type``","November 2020","|Complete|","14.0","|ranges|" +"`3448 `__","``transform_view``'s ``sentinel`` not comparable with ``iterator``","November 2020","","","|ranges|" +"`3449 `__","``take_view`` and ``take_while_view``'s ``sentinel`` not comparable with their ``const iterator``","November 2020","","","|ranges|" +"`3453 `__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","|Nothing To Do|","","|ranges|" +"`3455 `__","Incorrect Postconditions on ``unique_ptr`` move assignment","November 2020","|Nothing To Do|","" +"`3460 `__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","|Complete|","14.0" +"`3461 `__","``convertible_to``'s description mishandles cv-qualified ``void``","November 2020","|Nothing To Do|","" +"`3465 `__","``compare_partial_order_fallback`` requires ``F < E``","November 2020","|Complete|","14.0","|spaceship|" +"`3466 `__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","|Nothing To Do|","" +"`3467 `__","``bool`` can't be an integer-like type","November 2020","|Complete|","14.0" +"`3472 `__","``counted_iterator`` is missing preconditions","November 2020","|Complete|","14.0","|ranges|" +"`3473 `__","Normative encouragement in non-normative note","November 2020","|Nothing To Do|","","|format|" +"`3474 `__","Nesting ``join_views`` is broken because of CTAD","November 2020","","","|ranges|" +"`3476 `__","``thread`` and ``jthread`` constructors require that the parameters be move-constructible but never move construct the parameters","November 2020","","" +"`3477 `__","Simplify constraints for ``semiregular-box``","November 2020","","","|ranges|" +"`3482 `__","``drop_view``'s const begin should additionally require ``sized_range``","November 2020","|Complete|","14.0","|ranges|" +"`3483 `__","``transform_view::iterator``'s difference is overconstrained","November 2020","|Complete|","14.0","|ranges|" +"","","","","" +"`3391 `__","Problems with ``counted_iterator``/``move_iterator::base() const &``","February 2021","","","|ranges|" +"`3433 `__","``subrange::advance(n)`` has UB when ``n < 0``","February 2021","|Complete|","14.0","|ranges|" +"`3490 `__","``ranges::drop_while_view::begin()`` is missing a precondition","February 2021","|Nothing To Do|","","|ranges|" +"`3492 `__","Minimal improvements to ``elements_view::iterator``","February 2021","","","|ranges|" +"`3494 `__","Allow ranges to be conditionally borrowed","February 2021","Superseded by `P2017R1 `__","","|ranges|" +"`3495 `__","``constexpr launder`` makes pointers to inactive members of unions usable","February 2021","|Nothing To Do|","" +"`3500 `__","``join_view::iterator::operator->()`` is bogus","February 2021","","","|ranges|" +"`3502 `__","``elements_view`` should not be allowed to return dangling reference","February 2021","","","|ranges|" +"`3505 `__","``split_view::outer-iterator::operator++`` misspecified","February 2021","","","|ranges|" +"","","","","" +`2774 `__,"``std::function`` construction vs assignment","June 2021","","" +`2818 `__,"``::std::`` everywhere rule needs tweaking","June 2021","|Nothing To Do|","" +`2997 `__,"LWG 491 and the specification of ``{forward_,}list::unique``","June 2021","","" +`3410 `__,"``lexicographical_compare_three_way`` is overspecified","June 2021","","","|spaceship|" +`3430 `__,"``std::fstream`` & co. should be constructible from string_view","June 2021","","" +`3462 `__,"§[formatter.requirements]: Formatter requirements forbid use of ``fc.arg()``","June 2021","","","|format|" +`3481 `__,"``viewable_range`` mishandles lvalue move-only views","June 2021","Superseded by `P2415R2 `__","","|ranges|" +`3506 `__,"Missing allocator-extended constructors for ``priority_queue``","June 2021","|Complete|","14.0" +`3517 `__,"``join_view::iterator``'s ``iter_swap`` is underconstrained","June 2021","","","|ranges|" +`3518 `__,"Exception requirements on char trait operations unclear","June 2021","|Nothing To Do|","" +`3519 `__,"Incomplete synopses for ```` classes","June 2021","","" +`3520 `__,"``iter_move`` and ``iter_swap`` are inconsistent for ``transform_view::iterator``","June 2021","|Complete|","14.0","|ranges|" +`3521 `__,"Overly strict requirements on ``qsort`` and ``bsearch``","June 2021","|Nothing To Do|","" +`3522 `__,"Missing requirement on ``InputIterator`` template parameter for ``priority_queue`` constructors","June 2021","|Complete|","14.0","|ranges|" +`3523 `__,"``iota_view::sentinel`` is not always ``iota_view``'s sentinel","June 2021","","","|ranges|" +`3526 `__,"Return types of ``uses_allocator_construction_args`` unspecified","June 2021","","" +`3527 `__,"``uses_allocator_construction_args`` handles rvalue pairs of rvalue references incorrectly","June 2021","","" +`3528 `__,"``make_from_tuple`` can perform (the equivalent of) a C-style cast","June 2021","","" +`3529 `__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","|Complete|","14.0" +`3530 `__,"``BUILTIN-PTR-MEOW`` should not opt the type out of syntactic checks","June 2021","","" +`3532 `__,"``split_view::inner-iterator::operator++(int)`` should depend on ``Base``","June 2021","","","|ranges|" +`3533 `__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","|Complete|","14.0","|ranges|" +`3536 `__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","","","|chrono|" +`3539 `__,"``format_to`` must not copy models of ``output_iterator``","June 2021","","","|format|" +`3540 `__,"§[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","|Complete|","14.0","|format|" +`3541 `__,"``indirectly_readable_traits`` should be SFINAE-friendly for all types","June 2021","|Complete|","14.0","|ranges|" +`3542 `__,"``basic_format_arg`` mishandles ``basic_string_view`` with custom traits","June 2021","|Complete|","14.0","|format|" +`3543 `__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","|Nothing To Do|","","|ranges|" +`3544 `__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","|Complete|","14.0","|format|" +`3546 `__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","","|ranges|" +`3548 `__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","","" +`3549 `__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","|Complete|","14.0","|ranges|" +`3551 `__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","|Nothing To Do|","","|ranges|" +`3552 `__,"Parallel specialized memory algorithms should require forward iterators","June 2021","","" +`3553 `__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","","","|ranges|" +`3555 `__,"``{transform,elements}_view::iterator::iterator_concept`` should consider const-qualification of the underlying range","June 2021","","","|ranges|" +"","","","","" +`2191 `__,"Incorrect specification of ``match_results(match_results&&)``","October 2021","|Nothing To Do|","" +`2381 `__,"Inconsistency in parsing floating point numbers","October 2021","","" +`2762 `__,"``unique_ptr operator*()`` should be ``noexcept``","October 2021","","" +`3121 `__,"``tuple`` constructor constraints for ``UTypes&&...`` overloads","October 2021","","" +`3123 `__,"``duration`` constructor from representation shouldn't be effectively non-throwing","October 2021","","","|chrono|" +`3146 `__,"Excessive unwrapping in ``std::ref/cref``","October 2021","|Complete|","14.0" +`3152 `__,"``common_type`` and ``common_reference`` have flaws in common","October 2021","","" +`3293 `__,"``move_iterator operator+()`` has incorrect constraints","October 2021","","","|ranges|" +`3361 `__,"``safe_range`` case","October 2021","|Nothing To Do|","","|ranges|" +`3392 `__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel","October 2021","|Complete|","14.0","|ranges|" +`3407 `__,"Some problems with the wording changes of P1739R4","October 2021","","","|ranges|" +`3422 `__,"Issues of ``seed_seq``'s constructors","October 2021","|Complete|","14.0" +`3470 `__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","|Complete|","14.0","|ranges|" +`3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0","|ranges|" +`3498 `__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","","" +`3535 `__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","","","|ranges|" +`3554 `__,"``chrono::parse`` needs ``const charT*`` and ``basic_string_view`` overloads","October 2021","","","|chrono|" +`3557 `__,"The ``static_cast`` expression in ``convertible_to`` has the wrong operand","October 2021","|Complete|","14.0" +`3559 `__,"Semantic requirements of ``sized_range`` is circular","October 2021","|Nothing To Do|","","|ranges|" +`3560 `__,"``ranges::equal`` and ``ranges::is_permutation`` should short-circuit for ``sized_ranges``","October 2021","","","|ranges|" +`3561 `__,"Issue with internal counter in ``discard_block_engine``","October 2021","","" +`3563 `__,"``keys_view`` example is broken","October 2021","","","|ranges|" +`3566 `__,"Constraint recursion for ``operator<=>(optional, U)``","October 2021","","","|spaceship|" +`3567 `__,"Formatting move-only iterators take two","October 2021","","","|format|" +`3568 `__,"``basic_istream_view`` needs to initialize ``value_``","October 2021","","","|ranges|" +`3570 `__,"``basic_osyncstream::emit`` should be an unformatted output function","October 2021","","" +`3571 `__,"``flush_emit`` should set ``badbit`` if the ``emit`` call fails","October 2021","","" +`3572 `__,"``copyable-box`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|" +`3573 `__,"Missing Throws element for ``basic_string_view(It begin, End end)``","October 2021","|Complete|","14.0" +`3574 `__,"``common_iterator`` should be completely ``constexpr``-able","October 2021","|Complete|","14.0","|ranges|" +`3580 `__,"``iota_view``'s ``iterator``'s binary ``operator+`` should be improved","October 2021","|Complete|","14.0","|ranges|" +`3581 `__,"The range constructor makes ``basic_string_view`` not trivially move constructible","October 2021","|Complete|","14.0","|ranges|" +`3585 `__,"``variant`` converting assignment with immovable alternative","October 2021","","" +`3589 `__,"The ``const`` lvalue reference overload of ``get`` for ``subrange`` does not constrain ``I`` to be ``copyable`` when ``N == 0``","October 2021","|Complete|","14.0","|ranges|" +`3590 `__,"``split_view::base() const &`` is overconstrained","October 2021","","","|ranges|" +`3591 `__,"``lazy_split_view::inner-iterator::base() &&`` invalidates outer iterators","October 2021","","","|ranges|" +`3592 `__,"``lazy_split_view`` needs to check the simpleness of Pattern","October 2021","","","|ranges|" +`3593 `__,"Several iterators' ``base() const &`` and ``lazy_split_view::outer-iterator::value_type::end()`` missing ``noexcept``","October 2021","","","|ranges|" +`3595 `__,"Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|" +"","","","","" +`3645 `__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0","" +"","","","","" diff --git a/docs/Status/Cxx2bPapers.csv b/docs/Status/Cxx2bPapers.csv new file mode 100644 index 000000000..f5ab6edad --- /dev/null +++ b/docs/Status/Cxx2bPapers.csv @@ -0,0 +1,40 @@ +"Paper #","Group","Paper Name","Meeting","Status","First released version" +"`P0881R7 `__","LWG","A Proposal to add stacktrace library","Autumn 2020","","" +"`P0943R6 `__","LWG","Support C atomics in C++","Autumn 2020","","" +"`P1048R1 `__","LWG","A proposal for a type trait to detect scoped enumerations","Autumn 2020","|Complete|","12.0" +"`P1679R3 `__","LWG","string contains function","Autumn 2020","|Complete|","12.0" +"","","","","","" +"`P1682R3 `__","LWG","std::to_underlying for enumerations","February 2021","|Complete|","13.0" +"`P2017R1 `__","LWG","Conditionally borrowed ranges","February 2021","","" +"`P2160R1 `__","LWG","Locks lock lockables","February 2021","","" +"`P2162R2 `__","LWG","Inheriting from std::variant","February 2021","|Complete|","13.0" +"`P2212R2 `__","LWG","Relax Requirements for time_point::clock","February 2021","","" +"`P2259R1 `__","LWG","Repairing input range adaptors and counted_iterator","February 2021","","" +"","","","","","" +"`P0401R6 `__","LWG","Providing size feedback in the Allocator interface","June 2021","", +"`P0448R4 `__","LWG","A strstream replacement using span as buffer","June 2021","","" +"`P1132R8 `__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","","" +"`P1328R1 `__","LWG","Making std::type_info::operator== constexpr","June 2021","","" +"`P1425R4 `__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0" +"`P1518R2 `__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0" +"`P1659R3 `__","LWG","starts_with and ends_with","June 2021","","" +"`P1951R1 `__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","|Complete|","14.0" +"`P1989R2 `__","LWG","Range constructor for std::string_view","June 2021","|Complete|","14.0" +"`P2136R3 `__","LWG","invoke_r","June 2021","","" +"`P2166R1 `__","LWG","A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr","June 2021","|Complete|","13.0" +"","","","","","" +"`P0288R9 `__","LWG","``any_invocable``","October 2021","","" +"`P0798R8 `__","LWG","Monadic operations for ``std::optional``","October 2021","|Complete|","14.0" +"`P0849R8 `__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","|Complete|","14.0" +"`P1072R10 `__","LWG","``basic_string::resize_and_overwrite``","October 2021","|Complete|","14.0" +"`P1147R1 `__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0" +"`P1272R4 `__","LWG","Byteswapping for fun&&nuf","October 2021","|Complete|","14.0" +"`P1675R2 `__","LWG","``rethrow_exception`` must be allowed to copy","October 2021","","" +"`P2077R3 `__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","","" +"`P2251R1 `__","LWG","Require ``span`` & ``basic_string_view`` to be Trivially Copyable","October 2021","|Complete|","14.0" +"`P2301R1 `__","LWG","Add a ``pmr`` alias for ``std::stacktrace``","October 2021","","" +"`P2321R2 `__","LWG","``zip``","October 2021","|In Progress|","" +"`P2340R1 `__","LWG","Clarifying the status of the 'C headers'","October 2021","","" +"`P2393R1 `__","LWG","Cleaning up ``integer``-class types","October 2021","","" +"`P2401R0 `__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","|Complete|","14.0" +"","","","","","" diff --git a/docs/Status/Format.rst b/docs/Status/Format.rst new file mode 100644 index 000000000..35d8adfca --- /dev/null +++ b/docs/Status/Format.rst @@ -0,0 +1,49 @@ +.. format-status: + +================================ +libc++ Format Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +======== + +This document contains the status of the C++20 Format library in libc++. It is used to +track both the status of the sub-projects of the Format library and who is assigned to +these sub-projects. This is imperative to effective implementation so that work is not +duplicated and implementors are not blocked by each other. + + +If you are interested in contributing to the libc++ Format library, please send +a message to the #libcxx channel in the LLVM discord. Please *do not* start +working on any of the assigned items below. + + +Sub-Projects in the Format library +================================== + +.. csv-table:: + :file: FormatPaper.csv + :header-rows: 1 + :widths: auto + + +Misc. Items and TODOs +===================== + +(Please mark all Format-related TODO comments with the string ``TODO FMT``, so we +can find them easily.) + + +Paper and Issue Status +====================== + +.. csv-table:: + :file: FormatIssues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/FormatIssues.csv b/docs/Status/FormatIssues.csv new file mode 100644 index 000000000..473aba8ea --- /dev/null +++ b/docs/Status/FormatIssues.csv @@ -0,0 +1,10 @@ +Number,Name,Assignee,Patch,Status,First released version +`P0645 `_,"Text Formatting",Mark de Wever,,|Complete|,Clang 14 +`P1652 `_,"Printf corner cases in std::format",Mark de Wever,"`D103433 `__, `D114001 `__",|Complete|,Clang 14 +`P1892 `_,"Extended locale-specific presentation specifiers for std::format",Mark de Wever,`D103368 `__,|Complete|,Clang 14 +`P1868 `_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)",Mark de Wever,"`D103413 `__ `D103425 `__ `D103670 `__",|Complete|,Clang 14 +`P2216 `_,"std::format improvements",Mark de Wever,,|In Progress|, +`P2418 `__,"Add support for ``std::generator``-like types to ``std::format``",Mark de Wever,,|In Progress|, + +`P1361 `_,"Integration of chrono with text formatting",,,|Not Started|, +`P2372 `__,"Fixing locale handling in chrono formatters",,,|Not Started|, diff --git a/docs/Status/FormatPaper.csv b/docs/Status/FormatPaper.csv new file mode 100644 index 000000000..e45777ef1 --- /dev/null +++ b/docs/Status/FormatPaper.csv @@ -0,0 +1,49 @@ +Section,Description,Dependencies,Assignee,Patch,Status,First released version +`[charconv.to.chars] `_,"Fix integral conformance",,Mark de Wever,`D100722 `__,|Complete|,Clang 13 +`[charconv.to.chars] `_,"Add floating-point conversion",`D100722 `__,"Mark de Wever (Code provided by Stephan T. Lavavej of Microsoft)",`D70631 `__,|Complete|,Clang 14 +`[format.error] `_,"Class format_error",,Mark de Wever,`D92214 `__,|Complete|,Clang 13 +`[format.parse.ctx] `_,"Class template basic_format_parse_context",,Mark de Wever,`D93166 `__,|Complete|,Clang 13 +`[format.context] `_,"Class template basic_format_context",,Mark de Wever,`D103357 `__,|Complete|,Clang 14 +`[format.args] `_,"Class template basic_format_args",,Mark de Wever,`D103357 `__,|Complete|,Clang 14 +`[format.arg] `_,"Class template basic_format_arg",,Mark de Wever,`D103357 `__,|Complete|,Clang 14 +`[format.arg] `_,"Class template basic_format_arg - handle",,Mark de Wever,,|Complete|,Clang 14 +`[format.arg] `_,"Class template basic_format_arg - pointers",,Mark de Wever,,|Complete|,Clang 14 +`[format.arg.store] `_,"Class template format-arg-store",,Mark de Wever,`D103357 `__,|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - character types",,Mark de Wever,"`D96664 `__ `D103466 `__",|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - string types",,Mark de Wever,"`D96664 `__ `D103425 `__",|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - boolean type",,Mark de Wever,"`D96664 `__ `D103670 `__",|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - integral types",,Mark de Wever,"`D96664 `__ `D103433 `__",|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - floating-point types",`D70631 `__,Mark de Wever,`D114001 `__,|Complete|,Clang 14 +`[format.formatter.spec] `_,"Formatter specializations - pointer types",,Mark de Wever,,|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - character types",,Mark de Wever,`D103368 `__,|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - string types",`D103379 `__,Mark de Wever,"`D103368 `__ `D103413 `__",|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - boolean type",`D103379 `__,Mark de Wever,"`D103368 `__ `D103413 `__",|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - integral types",,Mark de Wever,`D103368 `__,|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - floating-point types",,Mark de Wever,`D114001 `__,|Complete|,Clang 14 +`[format.string.std] `_,"Standard format specifiers - pointer types",,Mark de Wever,,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat(string_view fmt, format_args args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat(wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat(const locale& loc, string_view fmt, format_args args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat(const locale& loc, wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to(Out out, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat_to(Out out, string_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat_to(Out out, wstring_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat_to(Out out, const locale& loc, string_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - vformat_to(Out out, const locale& loc, wstring_view fmt,format_args_t, wchar_t> args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to_n(Out out, iter_difference_t n, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to_n(Out out, iter_difference_t n, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - formatted_size(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - formatted_size(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - formatted_size(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - formatted_size(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,|Complete|,Clang 14 +`[format.functions] `_,"Format functions - Improve performance format_to_n",,Mark de Wever,`D110499 `__,|Review|, +`[format.functions] `_,"Format functions - Improve performance formatted size",,Mark de Wever,`D110500 `__,|Review|, +`[format.functions] `_,"`P2216 `_ - Compile-time checks",,Mark de Wever,,|In Progress|, +`[format.functions] `_,"`P2216 `_ - Binary size",,Mark de Wever,`D110494 `__,|Complete|,Clang 14 diff --git a/docs/Status/Ranges.rst b/docs/Status/Ranges.rst new file mode 100644 index 000000000..30546ed09 --- /dev/null +++ b/docs/Status/Ranges.rst @@ -0,0 +1,56 @@ +.. ranges-status: + +================================ +libc++ Ranges Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +This document contains the status of the C++20 Ranges library in libc++. It is used to +track both the status of the sub-projects of the ranges library and who is assigned to +these sub-projects. This is imperative to effective implementation so that work is not +duplicated and implementors are not blocked by each other. + +If you are interested in contributing to the libc++ Ranges library, please send a message +to the #libcxx channel in the LLVM discord. Please *do not* start working on any of the +assigned items below. + + +Sub-Projects in the One Ranges Proposal +======================================= + +.. csv-table:: + :file: RangesPaper.csv + :header-rows: 1 + :widths: auto + +.. csv-table:: + :file: RangesAlgorithms.csv + :header-rows: 1 + :widths: auto + + +Misc. Items and TODOs +==================================== + +(Note: files with required updates will contain the TODO at the beginning of the list item +so they can be easily found via global search.) + + * TODO(XX_SPACESHIP_CONCEPTS): when spaceship support is added to various STL types, we need to update some concept tests. + +Paper and Issue Status +==================================== + +(Note: stolen from MSVC `here `_.) + +.. csv-table:: + :file: RangesIssues.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/RangesAlgorithms.csv b/docs/Status/RangesAlgorithms.csv new file mode 100644 index 000000000..155e6b880 --- /dev/null +++ b/docs/Status/RangesAlgorithms.csv @@ -0,0 +1,100 @@ +Category,Algorithm,Assignee,CL,Complete +Search,any_of,Christopher Di Bella,`D105793 `_ +Search,all_of,Christopher Di Bella,`D105793 `_ +Search,none_of,Christopher Di Bella,`D105793 `_ +Search,find,Christopher Di Bella,`D105456 `_ +Search,find_if,Christopher Di Bella,`D105792 `_ +Search,find_if_not,Christopher Di Bella,`D105792 `_ +Search,find_first_of,Not assigned,n/a,Not started +Search,adjacent_find,Not assigned,n/a,Not started +Search,mismatch,Not assigned,n/a,Not started +Search,equal,Not assigned,n/a,Not started +Search,lexicographical_compare,Not assigned,n/a,Not started +Search,partition_point,Christopher Di Bella,`D105794 `_,Under review +Search,lower_bound,Christopher Di Bella,`D105795 `_,Under review +Search,upper_bound,Christopher Di Bella,`D105795 `_,Under review +Search,equal_range,Christopher Di Bella,n/a,Not started +Search,binary_search,Christopher Di Bella,n/a,Not started +Search,min,Not assigned,n/a,Not started +Search,max,Not assigned,n/a,Not started +Search,minmax,Not assigned,n/a,Not started +Search,min_element,Not assigned,n/a,Not started +Search,max_element,Not assigned,n/a,Not started +Search,minmax_element,Not assigned,n/a,Not started +Search,count,Not assigned,n/a,Not started +Search,count_if,Not assigned,n/a,Not started +Search,search,Not assigned,n/a,Not started +Search,search_n,Not assigned,n/a,Not started +Search,find_end,Not assigned,n/a,Not started +Read-only,is_partitioned,Christopher Di Bella,`D105794 `_,Under review +Read-only,is_sorted,Not assigned,n/a,Not started +Read-only,is_sorted_unitl,Not assigned,n/a,Not started +Read-only,includes,Not assigned,n/a,Not started +Read-only,is_heap,Not assigned,n/a,Not started +Read-only,is_heap_until,Not assigned,n/a,Not started +Read-only,clamp,Not assigned,n/a,Not started +Read-only,is_permutation,Not assigned,n/a,Not started +Read-only,for_each,Not assigned,n/a,Not started +Read-only,for_each_n,Not assigned,n/a,Not started +Write,copy,Not assigned,n/a,Not started +Write,copy_if,Not assigned,n/a,Not started +Write,copy_n,Not assigned,n/a,Not started +Write,copy_backward,Not assigned,n/a,Not started +Write,move,Not assigned,n/a,Not started +Write,move_backward,Not assigned,n/a,Not started +Write,fill,Not assigned,n/a,Not started +Write,fill_n,Not assigned,n/a,Not started +Write,transform,Not assigned,n/a,Not started +Write,generate,Not assigned,n/a,Not started +Write,generate_nNot assigned,n/a,Not started +Write,remove_copy,Not assigned,n/a,Not started +Write,remove_copy_if,Not assigned,n/a,Not started +Write,replace,Not assigned,n/a,Not started +Write,replace_if,Not assigned,n/a,Not started +Write,replace_copy,Not assigned,n/a,Not started +Write,replace_copy_if,Not assigned,n/a,Not started +Write,swap_ranges,Not assigned,n/a,Not started +Write,reverse_copy,Not assigned,n/a,Not started +Write,rotate_copy,Not assigned,n/a,Not started +Write,sample,Not assigned,n/a,Not started +Write,unique_copy,Not assigned,n/a,Not started +Write,partition_copy,Not assigned,n/a,Not started +Write,partial_sort_copy,Not assigned,n/a,Not started +Merge,merge,Not assigned,n/a,Not started +Merge,set_difference,Not assigned,n/a,Not started +Merge,set_intersection,Not assigned,n/a,Not started +Merge,set_symmetric_difference,Not assigned,n/a,Not started +Merge,set_union,Not assigned,n/a,Not started +Permutation,remove,Not assigned,n/a,Not started +Permutation,remove_if,Not assigned,n/a,Not started +Permutation,reverse,Not assigned,n/a,Not started +Permutation,rotate,Not assigned,n/a,Not started +Permutation,shuffle,Not assigned,n/a,Not started +Permutation,unique,Not assigned,n/a,Not started +Permutation,partition,Not assigned,n/a,Not started +Permutation,stable_partition,Not assigned,n/a,Not started +Permutation,sort,Not assigned,n/a,Not started +Permutation,stable_sort,Not assigned,n/a,Not started +Permutation,partial_sort,Not assigned,n/a,Not started +Permutation,nth_element,Not assigned,n/a,Not started +Permutation,inplace_merge,Not assigned,n/a,Not started +Permutation,make_heap,Not assigned,n/a,Not started +Permutation,push_heap,Not assigned,n/a,Not started +Permutation,pop_heap,Not assigned,n/a,Not started +Permutation,sort_heap,Not assigned,n/a,Not started +Permutation,prev_permutation,Not assigned,n/a,Not started +Permutation,next_permutation,Not assigned,n/a,Not started +Uninitialised memory,uninitialized_copy,Konstantin Varlamov,`D116023 `_,✅ +Uninitialised memory,uninitialized_copy_n,Konstantin Varlamov,`D116023 `_,✅ +Uninitialised memory,uninitialized_fill,Konstantin Varlamov,`D115626 `_,✅ +Uninitialised memory,uninitialized_fill_n,Konstantin Varlamov,`D115626 `_,✅ +Uninitialised memory,uninitialized_move,Konstantin Varlamov,`D116023 `_,✅ +Uninitialised memory,uninitialized_move_n,Konstantin Varlamov,`D116023 `_,✅ +Uninitialised memory,uninitialized_default_construct,Konstantin Varlamov,`D115315 `_,✅ +Uninitialised memory,uninitialized_default_construct_n,Konstantin Varlamov,`D115315 `_,✅ +Uninitialised memory,uninitialized_value_construct,Konstantin Varlamov,`D115626 `_,✅ +Uninitialised memory,uninitialized_value_construct_n,Konstantin Varlamov,`D115626 `_,✅ +Uninitialised memory,destroy,Konstantin Varlamov,`D116078 `_,✅ +Uninitialised memory,destroy_n,Konstantin Varlamov,`D116078 `_,✅ +Uninitialised memory,destroy_at,Konstantin Varlamov,`D116078 `_,✅ +Uninitialised memory,construct_at,Konstantin Varlamov,`D116078 `_,✅ diff --git a/docs/Status/RangesIssues.csv b/docs/Status/RangesIssues.csv new file mode 100644 index 000000000..728742d5b --- /dev/null +++ b/docs/Status/RangesIssues.csv @@ -0,0 +1,33 @@ +"Number","Name","Status","First released version" +`P0896R4 `__,,, +`P1035R7 `__,Input Range Adaptors,, +`P1207R4 `__,Movability Of Single-Pass Iterators,, +`P1243R4 `__,Rangify New Algorithms,, +`P1248R1 `__,Fixing Relations,|Complete|,13.0 +`P1252R2 `__,Ranges Design Cleanup,, +`P1391R4 `__,Range Constructor For string_view,|Complete|,14.0 +`P1456R1 `__,Move-Only Views,, +`P1474R1 `__,Helpful Pointers For contiguous_iterator,, +`P1522R1 `__,Iterator Difference Type And Integer Overflow,, +`P1523R1 `__,Views And Size Types,, +`P1638R1 `__,basic_istream_view::iterator Should Not Be Copyable,, +`P1716R3 `__,Range Comparison Algorithms Are Over-Constrained,, +`P1739R4 `__,Avoiding Template Bloat For Ranges,, +`P1862R1 `__,Range Adaptors For Non-Copyable Iterators,, +`P1870R1 `__,safe_range,, +`P1871R1 `__,disable_sized_sentinel_for,|Complete|,14.0 +`P1878R1 `__,Constraining Readable Types,, +`P1970R2 `__,ranges::ssize,, +`P1983R0 `__,Fixing Minor Ranges Issues,, +`P1994R1 `__,elements_view Needs Its Own sentinel,, +`P2091R0 `__,Fixing Issues With Range Access CPOs,, +`P2106R0 `__,Range Algorithm Result Types,, + +`P2325R3 `__,Views should not be required to be default constructible ,, +`P2328R1 `__,join_view should join all views of ranges,, +`P2210R2 `__,Superior String Splitting,, +`P2281R1 `__,Clarifying range adaptor objects,|Complete|,14.0 +`P2367R0 `__,Remove misuses of list-initialization from Clause 24,, + +`P2415 `__,"What is a ``view``",|Complete|,14.0 +`P2432 `__,"Fix ``istream_view``",, diff --git a/docs/Status/RangesPaper.csv b/docs/Status/RangesPaper.csv new file mode 100644 index 000000000..e6fddabbd --- /dev/null +++ b/docs/Status/RangesPaper.csv @@ -0,0 +1,159 @@ +Section,Description,Dependencies,Assignee,Complete +`[tuple.helper] `_,Update includes.,None,Konstantin Varlamov,Not started +`[range.cmp] `_,"| `ranges::equal_to `_ +| `ranges::not_equal_to `_ +| `ranges::less `_ +| `ranges::greater `_ +| `ranges::less_equal `_ +| `ranges::greater_equal `_",None,Zoe Carver,✅ +`[readable.traits] `_,"| `indirectly_readable_traits `_ +| `iter_value_t `_",None,Christopher Di Bella,✅ +`[incrementable.traits] `_,"| `incrementable_traits `_ +| `iter_difference_t `_",,Christopher Di Bella,✅ +`[iterator.traits] `_,`Updates to iterator_traits `_,"| indirectly_readable_traits +| incrementable_traits",Christopher Di Bella,✅ +`[special.mem.concepts] `_,"| `nothrow-input-iterator `_ +| `nothrow-sentinel-for `_ +| `nothrow-input-range `_ +| `nothrow-forward-iterator `_ +| `nothrow-forward-range `_","| [iterator.concepts] +| [range.refinements]",Konstantin Varlamov,✅ +`[specialized.algorithms] `_,"| `ranges::uninitialized_default_construct `_ +| `ranges::uninitialized_default_construct_n `_ +| `ranges::uninitialized_value_construct `_ +| `ranges::uninitialized_value_construct_n `_ +| `ranges::uninitialized_copy `_ +| `ranges::uninitialized_copy_n `_ +| `ranges::uninitialized_move `_ +| `ranges::uninitialized_move_n `_ +| `ranges::uninitialized_fill `_ +| `ranges::uninitialized_fill_n `_ +| `ranges::construct_at `_ +| `ranges::destroy `_ +| `ranges::destroy_at `_ +| `ranges::destroy_n `_",[special.mem.concepts],Konstantin Varlamov,✅ +`[strings] `_,Adds begin/end and updates const_iterator.,[iterator.concepts],Unassigned,Not started +`[views.span] `_,Same as [strings],[iterator.concepts],Unassigned,Not started +`[iterator.cust.move] `_,`ranges::iter_move `_,,Zoe Carver,✅ +`[iterator.cust.swap] `_,`ranges::iter_swap `_,iter_value_t,Zoe Carver,✅ +`[iterator.concepts] `_,"| `indirectly_readable `_ +| `indirectly_writable `_ +| `weakly_incrementable `_ +| `incrementable `_ +| `input_or_output_iterator `_ +| `sentinel_for `_ +| `sized_sentinel_for `_ +| `input_iterator `_ +| `output_iterator `_ +| `forward_iterator `_ +| `bidirectional_iterator `_ +| `random_access_iterator `_ +| `contiguous_iterator `_",,Various,✅ +`[indirectcallable.indirectinvocable] `_," +| `indirectly_unary_invocable `_ +| `indirectly_regular_unary_invocable `_ +| `indirectly_unary_predicate `_ +| `indirectly_binary_predicate `_ +| `indirectly_equivalence_relation `_ +| `indirectly_strict_weak_order `_",[readable.traits],Louis Dionne,✅ +`[projected] `_,`ranges::projected `_,[iterator.concepts],Louis Dionne,✅ +`[common.alg.req] `_: pt. 1,"| `indirectly_movable `_ +| `indirectly_movable_storable `_ +| indirectly_copyable +| indirectly_copyable_storable",[iterator.concepts],Zoe Carver,In progress +`[common.alg.req] `_: pt. 2,`indirectly_swappable `_,"| [iterator.concepts] +| [iterator.cust.swap]",Zoe Carver,✅ +`[common.alg.req] `_: pt. 3,`indirectly_comparable `_,[projected],Nikolas Klauser,✅ +`[common.alg.req] `_: pt. 4,"| permutable +| mergeable +| sortable",[iterator.concepts],Unassigned,Not started +`[std.iterator.tags] `_,,[iterator.traits],Unassigned,Not started +`[range.iter.ops] `_,"| `ranges::advance `_ +| `ranges::distance `_ +| `ranges::next `_ +| `ranges::prev `_",[iterator.concepts],Christopher Di Bella and Arthur O'Dwyer,✅ +`[predef.iterators] `_," +| Updates to reverse_iterator +| Updates to back_insert_iterator +| Updates to front_insert_iterator +| Updates to move_iterator","| [iterator.concepts] +| [iterator.cust.swap] +| [iterator.cust.move]",Unassigned,Not started +`[move.sentinel] `_,move_sentinel,[predef.iterators],Unassigned,Not started +`[common.iterator] `_,`common_iterator `_,"| [iterator.concepts] +| [iterator.cust.swap] +| [iterator.cust.move]",Zoe Carver,✅ +`[default.sentinel] `_,`std::default_sentinel_t `_,No dependencies,Zoe Carver,✅ +`[counted.iterator] `_,`counted_iterator `_,"| [iterator.concepts] +| [iterator.cust.swap] +| [iterator.cust.move] +| [default.sentinels]",Zoe Carver,✅ +`[stream.iterators] `_," +| Updates to istream_iterator +| Updates to ostream_iterator +| Updates to istreambuf_iterator +| Updates to ostreambuf_iterator +",[default.sentinels],Unassigned,Not started +`[range.access] `_,"| `ranges::begin `_ +| `ranges::end `_ +| `range::cbegin `_ +| `ranges::cend `_ +| ranges::rbegin +| ranges::rend +| ranges::crbegin +| ranges::crend +| `ranges::size `_ +| `ranges::ssize `_ +| `ranges::empty `_ +| `ranges::data `_ +| `ranges::cdata `_",[iterator.concepts],Christopher Di Bella and Zoe Carver,In progress +`[range.range] `_,"| `ranges::range `_ +| `ranges::borrowed_range `_ +| `ranges::enable_borrowed_range `_ +| `ranges::iterator_t `_ +| `ranges::sentinel_t `_ +| `ranges::range_difference_t `_ +| `ranges::range_size_t `_ +| `ranges::range_value_t `_ +| `ranges::range_reference_t `_ +| `ranges::range_rvalue_reference_t `_",[range.access],Christopher Di Bella,✅ +`[range.sized] `_,"| `ranges::sized_range `_ +| `ranges::disable_sized_range `_","| [range.primitives] +| [range.range]",Christopher Di Bella,✅ +`[range.view] `_,"| `ranges::enable_view `_ +| `ranges::view_base `_ +| `ranges::view `_",[range.range],Louis Dionne,✅ +`[range.refinements] `_,"| `ranges::output_range `_ +| `ranges::input_range `_ +| `ranges::forward_range `_ +| `ranges::bidirectional_range `_ +| `ranges::random_access_range `_ +| `ranges::contiguous_range `_ +| `ranges::common_range `_",[range.range],Christopher Di Bella,✅ +`[range.refinements]`_,`ranges::viewable_range `_,[range.range],Louis Dionne,✅ +`[range.utility.helpers] `_,"| `simple-view `_ +| `has-arrow `_ +| `not-same-as `_","| [range.range] +| [iterator.concept.input]",Zoe Carver,✅ +`[view.interface] `_,"`ranges::view_interface `_","| [ranges.range] +| [range.view] +| [range.iterator.op.prev] +| [range.refinements]",Zoe Carver,✅ +`[range.subrange] `_,`ranges::subrange `_,[view.interface],Zoe Carver,✅ +`[range.dangling] `_,"| `ranges::dangling `_ +| `ranges::borrowed_iterator_t `_ +| `ranges::borrowed_subrange_t `_","| [range.range] +| [range.subrange]",Christopher Di Bella,✅ +`[range.empty] `_,`empty_view `_,[view.interface],Zoe Carver,✅ +`[range.single] `_,`single_view `_,[view.interface],Zoe Carver,✅ +`[range.iota] `_,`iota_view `_,[range.all],Zoe Carver,✅ +`[range.all] `_,`view::all `_,"[range.subrange], [range.view.ref]",Zoe Carver,✅ +`[range.ref.view] `_,`ref_view `_,[view.interface],Zoe Carver,✅ +`[range.filter] `_,`filter_view `_,[range.all],Louis Dionne,Under review +`[range.transform] `_,`transform_view `_,[range.all],Zoe Carver,✅ +`[range.take] `_,`take_view `_,[range.all],Zoe Carver,✅ +`[range.join] `_,`join_view `_,[range.all],Zoe Carver,✅ +`[range.split] `_,`split_view `_,[range.all],Zoe Carver,In progress +`[range.counted] `_,`view::counted `_,[range.subrange],Zoe Carver,✅ +`[range.common] `_,`common_view `_,[range.all],Zoe Carver,✅ +`[range.reverse] `_,`reverse_view `_,[range.all],Zoe Carver,✅ diff --git a/docs/Status/Spaceship.rst b/docs/Status/Spaceship.rst new file mode 100644 index 000000000..d596c1128 --- /dev/null +++ b/docs/Status/Spaceship.rst @@ -0,0 +1,53 @@ +.. spaceship-status: + +============================================== +libc++ Spaceship Operator Status (operator<=>) +============================================== + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +This document contains the status of the C++20 spaceship operator support +in libc++. It is used to track both the status of the sub-projects of the effort +and who is assigned to these sub-projects. This is imperative to effective +implementation so that work is not duplicated and implementors are not blocked +by each other. + +If you are interested in contributing to this effort, please send a message +to the #libcxx channel in the LLVM discord. Please *do not* start working on any +of the assigned items below. + + +Sub-Projects in the Implementation Effort +========================================= + +.. csv-table:: + :file: SpaceshipProjects.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-strongorder] ``std::strong_order(long double, long double)`` is not yet implemented. + + +Misc. Items and TODOs +==================================== + +(Note: files with required updates will contain the TODO at the beginning of the +list item so they can be easily found via global search.) + + +Paper and Issue Status +==================================== + +.. csv-table:: + :file: SpaceshipPapers.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/SpaceshipPapers.csv b/docs/Status/SpaceshipPapers.csv new file mode 100644 index 000000000..82eea1bf9 --- /dev/null +++ b/docs/Status/SpaceshipPapers.csv @@ -0,0 +1,10 @@ +"Number","Name","Status","First released version" +`P1614R2 `_,The Mothership has Landed,|In Progress|, +`P2404R0 `_,"Relaxing equality_comparable_with's, totally_ordered_with's, and three_way_comparable_with's common reference requirements to support move-only types",, +`P2405R0 `_,nullopt_t and nullptr_t should both have operator<=> and operator==,, +`LWG3330 `_,Include from most library headers,"|Complete|","13.0" +`LWG3347 `_,"std::pair now requires T and U to be less-than-comparable",|Nothing To Do|, +`LWG3350 `_,Simplify return type of lexicographical_compare_three_way,|Nothing To Do|, +`LWG3360 `_,three_way_comparable_with is inconsistent with similar concepts,|Nothing To Do|, +`LWG3380 `_,common_type and comparison categories,|Nothing To Do|, +`LWG3395 `_,Definition for three-way comparison needs to be updated,|Nothing To Do|, diff --git a/docs/Status/SpaceshipProjects.csv b/docs/Status/SpaceshipProjects.csv new file mode 100644 index 000000000..25bb7d077 --- /dev/null +++ b/docs/Status/SpaceshipProjects.csv @@ -0,0 +1,82 @@ +Section,Description,Dependencies,Assignee,Complete +| `[cmp.concept] `_,"| `three_way_comparable `_ +| `three_way_comparable_with `_",None,Ruslan Arutyunyan,|Complete| +| `[cmp.result] `_,| `compare_three_way_result `_,None,Arthur O'Dwyer,|Complete| +| `[expos.only.func] `_,"| `synth-three-way `_ +| `synth-three-way-result `_",[cmp.concept],Kent Ross,|Complete| +| `[comparisons.three.way] `_,| `compare_three_way `_,[cmp.concept],Arthur O'Dwyer,|Complete| +| `[cmp.alg] `_,"| `strong_order `_ +| `weak_order `_ +| `partial_order `_ +| `strong_order_fallback `_ +| `weak_order_fallback `_ +| `partial_order_fallback `_",None,Arthur O'Dwyer,|Complete| [#note-strongorder]_ +| `[alg.three.way] `_,| `lexicographical_compare_three_way `_,[comparisons.three.way],Christopher Di Bella,|In Progress| +| `[coroutine.handle.compare] `_,| `coroutine_handle `_,[comparisons.three.way],Chuanqi Xu,|Complete| +| `[pairs.spec] `_,| `pair `_,[expos.only.func],Kent Ross,|Complete| +| `[syserr.errcat.nonvirtuals] `_,| error_category,[comparisons.three.way],Unassigned,|Not Started| +| `[syserr.compare] `_,"| error_code +| error_condition",None,Unassigned,|Not Started| +| `[tuple.rel] `_,| `tuple `_,[expos.only.func],Kent Ross,|Complete| +"| `[optional.relops] `_ +| `[optional.nullops] `_ +| `[optional.comp.with.t] `_","| optional +| nullopt",None,Kent Ross,|In Progress| +"| `[variant.relops] `_ +| `[variant.monostate.relops] `_","| monostate +| variant",None,Kent Ross,|In Progress| +| `[unique.ptr.special] `_,| unique_ptr,[comparisons.three.way],Unassigned,|Not Started| +| `[util.smartptr.shared.cmp] `_,| shared_ptr,[comparisons.three.way],Unassigned,|Not Started| +| `[type.index.members] `_,| type_index,None,Unassigned,|Not Started| +| `[charconv.syn] `_,| to_chars_result,None,Mark de Wever,|Complete| +| `[charconv.syn] `_,| from_chars_result,None,Mark de Wever,|Complete| +| `[stacktrace.entry.cmp] `_,| stacktrace_entry,None,Unassigned,|Not Started| +| `[stacktrace.basic.cmp] `_,| basic_stacktrace,[alg.three.way],Unassigned,|Not Started| +| `[string.cmp] `_,| `basic_string `_,None,Christopher Di Bella,|In Progress| +| `[string.view.comparison] `_,| `basic_string_view `_,None,Christopher Di Bella,|In Progress| +| `[array.syn] `_ (`general `_),| array,[expos.only.func],Unassigned,|Not Started| +| `[deque.syn] `_ (`general `_),| deque,[expos.only.func],Unassigned,|Not Started| +| `[forward.list.syn] `_ (`general `_),| forward_list,[expos.only.func],Unassigned,|Not Started| +| `[list.syn] `_ (`general `_),| list,[expos.only.func],Unassigned,|Not Started| +| `[vector.syn] `_ (`general `_),| vector,[expos.only.func],Unassigned,|Not Started| +| `[associative.map.syn] `_ (`general `_),"| map +| multimap",[expos.only.func],Unassigned,|Not Started| +| `[associative.set.syn] `_ (`general `_),"| multiset +| set",[expos.only.func],Unassigned,|Not Started| +| `[queue.ops] `_,| queue,None,Unassigned,|Not Started| +| `[stack.ops] `_,| stack,None,Unassigned,|Not Started| +| `[reverse.iter.cmp] `_,| reverse_iterator,None,Mikhail Maltsev,|Complete| +| `[move.iter.op.comp] `_,| move_iterator,None,Unassigned,|Not Started| +| `[counted.iter.cmp] `_,| counted_iterator,None,Unassigned,|Not Started| +| `[range.iota.iterator] `_,| ranges::iota_view::iterator,[concepts.cmp],Unassigned,|Not Started| +| `[range.transform.iterator] `_,| ranges::transform_view::iterator,[concepts.cmp],Unassigned,|Not Started| +| `[range.elements.iterator] `_,| ranges::elements_view::iterator,[concepts.cmp],Unassigned,|Not Started| +"| `[time.duration.comparisons] `_ +| `[time.point.comparisons] `_ +| `[time.cal.day.nonmembers] `_ +| `[time.cal.month.nonmembers] `_ +| `[time.cal.year.nonmembers] `_ +| `[time.cal.md.nonmembers] `_ +| `[time.cal.mdlast] `_ +| `[time.cal.ym.nonmembers] `_ +| `[time.cal.ymd.nonmembers] `_ +| `[time.cal.ymdlast.nonmembers] `_ +| `[time.zone.nonmembers] `_ +| `[time.zone.leap.nonmembers] `_ +| `[time.zone.link.nonmembers] `_","| chrono::duration +| chrono::time_point +| chrono::day +| chrono::month +| chrono::year +| chrono::month_day +| chrono::month_day_last +| chrono::year_month +| chrono::year_month_day +| chrono::year_month_day_last +| chrono::time_zone +| chrono::leap_second +| chrono::time_zone_link",None,Unassigned,|Not Started| +| `[fs.path.nonmember] `_,| filesystem::path,None,Unassigned,|Not Started| +| `[fs.dir.entry.obs] `_,| filesystem::directory_entry,None,Unassigned,|Not Started| +| `[re.submatch.op] `_,| sub_match,None,Unassigned,|Not Started| +| `[thread.thread.id] `_,| thread::id,None,Unassigned,|Not Started| diff --git a/docs/Status/Zip.rst b/docs/Status/Zip.rst new file mode 100644 index 000000000..db2cdfe29 --- /dev/null +++ b/docs/Status/Zip.rst @@ -0,0 +1,29 @@ +.. zip-status: + +=========================== +libc++ Zip Status (P2321R2) +=========================== + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + +Overview +======== + +This document contains the status of the C++2b zip implementation in libc++. +It is used to track both the status of the sub-projects of the effort and who +is assigned to these sub-projects. This avoids duplicating effort. + +If you are interested in contributing to this effort, please send a message +to the #libcxx channel in the LLVM discord. Please *do not* start working +on any items below that has already been assigned to someone else. + +Sub-projects in the Implementation Effort +========================================= + +.. csv-table:: + :file: ZipProjects.csv + :header-rows: 1 + :widths: auto diff --git a/docs/Status/ZipProjects.csv b/docs/Status/ZipProjects.csv new file mode 100644 index 000000000..4990d6b3e --- /dev/null +++ b/docs/Status/ZipProjects.csv @@ -0,0 +1,27 @@ +Section,Description,Dependencies,Assignee,Complete +| `[tuple.syn] `_, "`[tuple] basic_common_reference, common_type `_", None, Nikolas Klauser, |In Progress| +| `[tuple.tuple] `_, "`[tuple] constructor, assignment and swap overloads `_", None, Nikolas Klauser, |In Progress| +| `[utility.syn] `_, "[pair] basic_common_reference, common_type", None, Nikolas Klauser, |Not Started| +| `[pairs.pair] `_, "[pair] constructor, assignment and swap overloads", None, Nikolas Klauser, |Not Started| +"| `[memory.syn] `_ +| `[allocator.uses.construction] `_", "[pair] uses_allocator_construction_args overloads", None, Unassigned, |Not Started| +| `[vector.bool] `_, "[vector::reference] add const operator= overload", None, Nikolas Klauser, |Not Started| +| `[iterator.concept.winc] `_, "Update weakly_comparable", None, Unassigned, |Not Started| +| `[range.zip] `_, "zip_view", "| `zip_view::iterator` +| `zip_view::sentinel`", Unassigned, |Not Started| +| `[range.zip.iterator] `_, "zip_view::iterator", None, Unassigned, |Not Started| +| `[range.zip.sentinel] `_, "zip_view::sentinel", None, Unassigned, |Not Started| +| `[range.zip.transform.view] `_, "zip_transform_view", "| `zip_transform_view::iterator` +| `zip_transform_view::sentinel`", Unassigned, |Not Started| +| `[range.zip.transform.iterator] `_, "zip_transform_view::iterator", None, Unassigned, |Not Started| +| `[range.zip.transform.sentinel] `_, "zip_transform_view::sentinel", None, Unassigned, |Not Started| +| `[range.adjacent.view] `_, "adjacent_view", "| `adjacent_view::iterator` +| `adjacent_view::sentinel`", Unassigned, |Not Started| +| `[range.adjacent.iterator] `_, "adjacent_view::iterator", None, Unassigned, |Not Started| +| `[range.adjacent.sentinel] `_, "adjacent_view::sentinel", None, Unassigned, |Not Started| +| `[range.adjacent.transform.view] `_, "adjacent_transform_view", "| `adjacent_transform_view::iterator`, +| `adjacent_transform_view::sentinel`", Unassigned, |Not Started| +| `[range.adjacent.transform.iterator] `_, "adjacent_transform_view::iterator", None, Unassigned, |Not Started| +| `[range.adjacent.transform.sentinel] `_, "adjacent_transform_view::sentinel", None, Unassigned, |Not Started| +| `[ranges.syn] `_, "enable_borrowed_range zip_view and adjacent_view", "| `zip_view` +| `adjacent_view`", Unassigned, |Not Started| diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst index eaba21439..b5c7ae89c 100644 --- a/docs/TestingLibcxx.rst +++ b/docs/TestingLibcxx.rst @@ -8,9 +8,9 @@ Testing libc++ Getting Started =============== -libc++ uses LIT to configure and run its tests. +libc++ uses LIT to configure and run its tests. -The primary way to run the libc++ tests is by using `make check-libcxx`. +The primary way to run the libc++ tests is by using ``make check-cxx``. However since libc++ can be used in any number of possible configurations it is important to customize the way LIT builds and runs @@ -19,40 +19,29 @@ test libc++. Please see the `Lit Command Guide`_ for more information about LIT. -.. _LIT Command Guide: http://llvm.org/docs/CommandGuide/lit.html +.. _LIT Command Guide: https://llvm.org/docs/CommandGuide/lit.html -Setting up the Environment --------------------------- +Usage +----- -After building libc++ you must setup your environment to test libc++ using -LIT. - -#. Create a shortcut to the actual lit executable so that you can invoke it - easily from the command line. - - .. code-block:: bash - - $ alias lit='python path/to/llvm/utils/lit/lit.py' - -#. Tell LIT where to find your build configuration. - - .. code-block:: bash - - $ export LIBCXX_SITE_CONFIG=path/to/build-libcxx/test/lit.site.cfg - -Example Usage -------------- - -Once you have your environment set up and you have built libc++ you can run -parts of the libc++ test suite by simply running `lit` on a specified test or -directory. For example: +After building libc++, you can run parts of the libc++ test suite by simply +running ``llvm-lit`` on a specified test or directory. If you're unsure +whether the required libraries have been built, you can use the +`cxx-test-depends` target. For example: .. code-block:: bash - $ cd path/to/src/libcxx - $ lit -sv test/std/re # Run all of the std::regex tests - $ lit -sv test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test - $ lit -sv test/std/atomics test/std/threads # Test std::thread and std::atomic + $ cd + $ make -C cxx-test-depends # If you want to make sure the targets get rebuilt + $ /bin/llvm-lit -sv libcxx/test/std/re # Run all of the std::regex tests + $ /bin/llvm-lit -sv libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test + $ /bin/llvm-lit -sv libcxx/test/std/atomics libcxx/test/std/threads # Test std::thread and std::atomic + +In the default configuration, the tests are built against headers that form a +fake installation root of libc++. This installation root has to be updated when +changes are made to the headers, so you should re-run the `cxx-test-depends` +target before running the tests manually with `lit` when you make any sort of +change, including to the headers. Sometimes you'll want to change the way LIT is running the tests. Custom options can be specified using the `--param==` flag. The most common option @@ -62,29 +51,50 @@ that. However if you want to manually specify the option like so: .. code-block:: bash - $ lit -sv test/std/containers # Run the tests with the newest -std - $ lit -sv --param=std=c++03 test/std/containers # Run the tests in C++03 + $ /bin/llvm-lit -sv libcxx/test/std/containers # Run the tests with the newest -std + $ /bin/llvm-lit -sv libcxx/test/std/containers --param=std=c++03 # Run the tests in C++03 Occasionally you'll want to add extra compile or link flags when testing. You can do this as follows: .. code-block:: bash - $ lit -sv --param=compile_flags='-Wcustom-warning' - $ lit -sv --param=link_flags='-L/custom/library/path' + $ /bin/llvm-lit -sv libcxx/test --param=compile_flags='-Wcustom-warning' + $ /bin/llvm-lit -sv libcxx/test --param=link_flags='-L/custom/library/path' Some other common examples include: .. code-block:: bash # Specify a custom compiler. - $ lit -sv --param=cxx_under_test=/opt/bin/g++ test/std + $ /bin/llvm-lit -sv libcxx/test/std --param=cxx_under_test=/opt/bin/g++ - # Enable warnings in the test suite - $ lit -sv --param=enable_warnings=true test/std + # Disable warnings in the test suite + $ /bin/llvm-lit -sv libcxx/test --param=enable_warnings=False # Use UBSAN when running the tests. - $ lit -sv --param=use_sanitizer=Undefined + $ /bin/llvm-lit -sv libcxx/test --param=use_sanitizer=Undefined + +Using a custom site configuration +--------------------------------- + +By default, the libc++ test suite will use a site configuration that matches +the current CMake configuration. It does so by generating a ``lit.site.cfg`` +file in the build directory from one of the configuration file templates in +``libcxx/test/configs/``, and pointing ``llvm-lit`` (which is a wrapper around +``llvm/utils/lit/lit.py``) to that file. So when you're running +``/bin/llvm-lit``, the generated ``lit.site.cfg`` file is always loaded +instead of ``libcxx/test/lit.cfg.py``. If you want to use a custom site +configuration, simply point the CMake build to it using +``-DLIBCXX_TEST_CONFIG=``, and that site configuration +will be used instead. That file can use CMake variables inside it to make +configuration easier. + + .. code-block:: bash + + $ cmake -DLIBCXX_TEST_CONFIG= + $ make -C cxx-test-depends + $ /bin/llvm-lit -sv libcxx/test # will use your custom config file LIT Options @@ -95,9 +105,10 @@ LIT Options Command Line Options -------------------- -To use these options you pass them on the LIT command line as --param NAME or ---param NAME=VALUE. Some options have default values specified during CMake's -configuration. Passing the option on the command line will override the default. +To use these options you pass them on the LIT command line as ``--param NAME`` +or ``--param NAME=VALUE``. Some options have default values specified during +CMake's configuration. Passing the option on the command line will override the +default. .. program:: lit @@ -105,25 +116,20 @@ configuration. Passing the option on the command line will override the default. Specify the compiler used to build the tests. -.. option:: cxx_stdlib_under_test= +.. option:: stdlib= - **Values**: libc++, libstdc++ + **Values**: libc++, libstdc++, msvc - Specify the C++ standard library being tested. Unless otherwise specified - libc++ is used. This option is intended to allow running the libc++ test - suite against other standard library implementations. + Specify the C++ standard library being tested. The default is libc++ if this + option is not provided. This option is intended to allow running the libc++ + test suite against other standard library implementations. .. option:: std= - **Values**: c++98, c++03, c++11, c++14, c++17, c++2a + **Values**: c++03, c++11, c++14, c++17, c++20, c++2b Change the standard version used when building the tests. -.. option:: libcxx_site_config= - - Specify the site configuration to use when running the tests. This option - overrides the environment variable LIBCXX_SITE_CONFIG. - .. option:: cxx_headers= Specify the c++ standard library headers that are tested. By default the @@ -132,8 +138,7 @@ configuration. Passing the option on the command line will override the default. .. option:: cxx_library_root= Specify the directory of the libc++ library to be tested. By default the - library folder of the build directory is used. This option cannot be used - when use_system_cxx_lib is provided. + library folder of the build directory is used. .. option:: cxx_runtime_root= @@ -148,23 +153,10 @@ configuration. Passing the option on the command line will override the default. **Default**: False Enable or disable testing against the installed version of libc++ library. - Note: This does not use the installed headers. - -.. option:: use_lit_shell= - - Enable or disable the use of LIT's internal shell in ShTests. If the - environment variable LIT_USE_INTERNAL_SHELL is present then that is used as - the default value. Otherwise the default value is True on Windows and False - on every other platform. - -.. option:: compile_flags="" - - Specify additional compile flags as a space delimited string. - Note: This options should not be used to change the standard version used. - -.. option:: link_flags="" - - Specify additional link flags as a space delimited string. + This impacts whether the ``use_system_cxx_lib`` Lit feature is defined or + not. The ``cxx_library_root`` and ``cxx_runtime_root`` parameters should + still be used to specify the path of the library to link to and run against, + respectively. .. option:: debug_level= @@ -180,12 +172,6 @@ configuration. Passing the option on the command line will override the default. Run the tests using the given sanitizer. If LLVM_USE_SANITIZER was given when building libc++ then that sanitizer will be used by default. -.. option:: color_diagnostics - - Enable the use of colorized compile diagnostics. If the color_diagnostics - option is specified or the environment variable LIBCXX_COLOR_DIAGNOSTICS is - present then color diagnostics will be enabled. - .. option:: llvm_unwinder Enable the use of LLVM unwinder instead of libgcc. @@ -195,19 +181,28 @@ configuration. Passing the option on the command line will override the default. Path to the builtins library to use instead of libgcc. -Environment Variables ---------------------- +Writing Tests +------------- -.. envvar:: LIBCXX_SITE_CONFIG= +When writing tests for the libc++ test suite, you should follow a few guidelines. +This will ensure that your tests can run on a wide variety of hardware and under +a wide variety of configurations. We have several unusual configurations such as +building the tests on one host but running them on a different host, which add a +few requirements to the test suite. Here's some stuff you should know: - Specify the site configuration to use when running the tests. - Also see `libcxx_site_config`. - -.. envvar:: LIBCXX_COLOR_DIAGNOSTICS - - If ``LIBCXX_COLOR_DIAGNOSTICS`` is defined then the test suite will attempt - to use color diagnostic outputs from the compiler. - Also see `color_diagnostics`. +- All tests are run in a temporary directory that is unique to that test and + cleaned up after the test is done. +- When a test needs data files as inputs, these data files can be saved in the + repository (when reasonable) and referenced by the test as + ``// FILE_DEPENDENCIES: ``. Copies of these files or + directories will be made available to the test in the temporary directory + where it is run. +- You should never hardcode a path from the build-host in a test, because that + path will not necessarily be available on the host where the tests are run. +- You should try to reduce the runtime dependencies of each test to the minimum. + For example, requiring Python to run a test is bad, since Python is not + necessarily available on all devices we may want to run the tests on (even + though supporting Python is probably trivial for the build-host). Benchmarks ========== @@ -232,12 +227,11 @@ An example build would look like: .. code-block:: bash $ cd build - $ cmake [options] - $ make cxx-benchmarks + $ ninja cxx-benchmarks This will build all of the benchmarks under ``/benchmarks`` to be built against the just-built libc++. The compiled tests are output into -``build/benchmarks``. +``build/projects/libcxx/benchmarks``. The benchmarks can also be built against the platforms native standard library using the ``-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON`` CMake option. This @@ -260,8 +254,7 @@ For example: .. code-block:: bash - $ cd build/benchmarks - $ make cxx-benchmarks + $ cd build/projects/libcxx/benchmarks $ ./algorithms.libcxx.out # Runs all the benchmarks $ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst index 05721bf27..bd999f05c 100644 --- a/docs/UsingLibcxx.rst +++ b/docs/UsingLibcxx.rst @@ -1,3 +1,5 @@ +.. _using-libcxx: + ============ Using libc++ ============ @@ -5,138 +7,118 @@ Using libc++ .. contents:: :local: -Getting Started -=============== +Usually, libc++ is packaged and shipped by a vendor through some delivery vehicle +(operating system distribution, SDK, toolchain, etc) and users don't need to do +anything special in order to use the library. -If you already have libc++ installed you can use it with clang. +This page contains information about configuration knobs that can be used by +users when they know libc++ is used by their toolchain, and how to use libc++ +when it is not the default library used by their toolchain. + + +Using a different version of the C++ Standard +============================================= + +Libc++ implements the various versions of the C++ Standard. Changing the version of +the standard can be done by passing ``-std=c++XY`` to the compiler. Libc++ will +automatically detect what Standard is being used and will provide functionality that +matches that Standard in the library. .. code-block:: bash - $ clang++ -stdlib=libc++ test.cpp - $ clang++ -std=c++11 -stdlib=libc++ test.cpp + $ clang++ -std=c++17 test.cpp -On macOS and FreeBSD libc++ is the default standard library -and the ``-stdlib=libc++`` is not required. +.. warning:: + Using ``-std=c++XY`` with a version of the Standard that has not been ratified yet + is considered unstable. Libc++ reserves the right to make breaking changes to the + library until the standard has been ratified. -.. _alternate libcxx: - -If you want to select an alternate installation of libc++ you -can use the following options. - -.. code-block:: bash - - $ clang++ -std=c++11 -stdlib=libc++ -nostdinc++ \ - -I/include/c++/v1 \ - -L/lib \ - -Wl,-rpath,/lib \ - test.cpp - -The option ``-Wl,-rpath,/lib`` adds a runtime library -search path. Meaning that the systems dynamic linker will look for libc++ in -``/lib`` whenever the program is run. Alternatively the -environment variable ``LD_LIBRARY_PATH`` (``DYLD_LIBRARY_PATH`` on macOS) can -be used to change the dynamic linkers search paths after a program is compiled. - -An example of using ``LD_LIBRARY_PATH``: - -.. code-block:: bash - - $ clang++ -stdlib=libc++ -nostdinc++ \ - -I/include/c++/v1 - -L/lib \ - test.cpp -o - $ ./a.out # Searches for libc++ in the systems library paths. - $ export LD_LIBRARY_PATH=/lib - $ ./a.out # Searches for libc++ along LD_LIBRARY_PATH - -Using ```` -====================== - -Prior to LLVM 9.0, libc++ provides the implementation of the filesystem library -in a separate static library. Users of ```` and ```` -are required to link ``-lc++fs``. Prior to libc++ 7.0, users of -```` were required to link libc++experimental. - -Starting with LLVM 9.0, support for ```` is provided in the main -library and nothing special is required to use ````. Using libc++experimental and ```` -===================================================== +=================================================== Libc++ provides implementations of experimental technical specifications in a separate library, ``libc++experimental.a``. Users of ```` -headers may be required to link ``-lc++experimental``. +headers may be required to link ``-lc++experimental``. Note that not all +vendors ship ``libc++experimental.a``, and as a result, you may not be +able to use those experimental features. .. code-block:: bash - $ clang++ -std=c++14 -stdlib=libc++ test.cpp -lc++experimental - -Libc++experimental.a may not always be available, even when libc++ is already -installed. For information on building libc++experimental from source see -:ref:`Building Libc++ ` and -:ref:`libc++experimental CMake Options `. - -Also see the `Experimental Library Implementation Status `__ -page. + $ clang++ test.cpp -lc++experimental .. warning:: Experimental libraries are Experimental. * The contents of the ```` headers and ``libc++experimental.a`` library will not remain compatible between versions. * No guarantees of API or ABI stability are provided. - * When we implement the standardized version of an experimental feature, + * When the standardized version of an experimental feature is implemented, the experimental feature is removed two releases after the non-experimental version has shipped. The full policy is explained :ref:`here `. -Using libc++ on Linux -===================== -On Linux libc++ can typically be used with only '-stdlib=libc++'. However -some libc++ installations require the user manually link libc++abi themselves. -If you are running into linker errors when using libc++ try adding '-lc++abi' -to the link line. For example: +Using libc++ when it is not the system default +============================================== + +On systems where libc++ is provided but is not the default, Clang provides a flag +called ``-stdlib=`` that can be used to decide which standard library is used. +Using ``-stdlib=libc++`` will select libc++: .. code-block:: bash - $ clang++ -stdlib=libc++ test.cpp -lc++ -lc++abi -lm -lc -lgcc_s -lgcc + $ clang++ -stdlib=libc++ test.cpp -Alternately, you could just add libc++abi to your libraries list, which in -most situations will give the same result: +On systems where libc++ is the library in use by default such as macOS and FreeBSD, +this flag is not required. + + +.. _alternate libcxx: + +Using a custom built libc++ +=========================== + +Most compilers provide a way to disable the default behavior for finding the +standard library and to override it with custom paths. With Clang, this can +be done with: .. code-block:: bash - $ clang++ -stdlib=libc++ test.cpp -lc++abi + $ clang++ -nostdinc++ -nostdlib++ \ + -isystem /include/c++/v1 \ + -L /lib \ + -Wl,-rpath,/lib \ + -lc++ \ + test.cpp +The option ``-Wl,-rpath,/lib`` adds a runtime library search path, +which causes the system's dynamic linker to look for libc++ in ``/lib`` +whenever the program is loaded. -Using libc++ with GCC ---------------------- - -GCC does not provide a way to switch from libstdc++ to libc++. You must manually -configure the compile and link commands. - -In particular you must tell GCC to remove the libstdc++ include directories -using ``-nostdinc++`` and to not link libstdc++.so using ``-nodefaultlibs``. - -Note that ``-nodefaultlibs`` removes all of the standard system libraries and -not just libstdc++ so they must be manually linked. For example: +GCC does not support the ``-nostdlib++`` flag, so one must use ``-nodefaultlibs`` +instead. Since that removes all the standard system libraries and not just libc++, +the system libraries must be re-added manually. For example: .. code-block:: bash - $ g++ -nostdinc++ -I/include/c++/v1 \ - test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc + $ g++ -nostdinc++ -nodefaultlibs \ + -isystem /include/c++/v1 \ + -L /lib \ + -Wl,-rpath,/lib \ + -lc++ -lc++abi -lm -lc -lgcc_s -lgcc \ + test.cpp GDB Pretty printers for libc++ ------------------------------- +============================== -GDB does not support pretty-printing of libc++ symbols by default. Unfortunately -libc++ does not provide pretty-printers itself. However there are 3rd -party implementations available and although they are not officially -supported by libc++ they may be useful to users. +GDB does not support pretty-printing of libc++ symbols by default. However, libc++ does +provide pretty-printers itself. Those can be used as: -Known 3rd Party Implementations Include: +.. code-block:: bash -* `Koutheir's libc++ pretty-printers `_. + $ gdb -ex "source /utils/gdb/libcxx/printers.py" \ + -ex "python register_libcxx_printer_loader()" \ + Libc++ Configuration Macros @@ -151,7 +133,7 @@ thread safety annotations. **_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**: This macro is used to enable -Wthread-safety annotations on libc++'s - ``std::mutex`` and ``std::lock_guard``. By default these annotations are + ``std::mutex`` and ``std::lock_guard``. By default, these annotations are disabled and must be manually enabled by the user. **_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS**: @@ -165,33 +147,6 @@ thread safety annotations. headers. The intended use case is for clients who wish to use the libc++ headers without taking a dependency on the libc++ library itself. -**_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION**: - This macro is used to re-enable an extension in `std::tuple` which allowed - it to be implicitly constructed from fewer initializers than contained - elements. Elements without an initializer are default constructed. For example: - - .. code-block:: cpp - - std::tuple foo() { - return {"hello world", 42}; // default constructs error_code - } - - - Since libc++ 4.0 this extension has been disabled by default. This macro - may be defined to re-enable it in order to support existing code that depends - on the extension. New use of this extension should be discouraged. - See `PR 27374 `_ for more information. - - Note: The "reduced-arity-initialization" extension is still offered but only - for explicit conversions. Example: - - .. code-block:: cpp - - auto foo() { - using Tup = std::tuple; - return Tup{"hello world", 42}; // explicit constructor called. OK. - } - **_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS**: This macro disables the additional diagnostics generated by libc++ using the `diagnose_if` attribute. These additional diagnostics include checks for: @@ -247,20 +202,56 @@ C++17 Specific Configuration Macros This macro is used to re-enable all the features removed in C++17. The effect is equivalent to manually defining each macro listed below. -**_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS**: - This macro is used to re-enable the `set_unexpected`, `get_unexpected`, and - `unexpected` functions, which were removed in C++17. - **_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**: - This macro is used to re-enable `std::auto_ptr` in C++17. + This macro is used to re-enable `auto_ptr`. -C++2a Specific Configuration Macros: +**_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS**: + This macro is used to re-enable the `binder1st`, `binder2nd`, + `pointer_to_unary_function`, `pointer_to_binary_function`, `mem_fun_t`, + `mem_fun1_t`, `mem_fun_ref_t`, `mem_fun1_ref_t`, `const_mem_fun_t`, + `const_mem_fun1_t`, `const_mem_fun_ref_t`, and `const_mem_fun1_ref_t` + class templates, and the `bind1st`, `bind2nd`, `mem_fun`, `mem_fun_ref`, + and `ptr_fun` functions. + +**_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE**: + This macro is used to re-enable the `random_shuffle` algorithm. + +**_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS**: + This macro is used to re-enable `set_unexpected`, `get_unexpected`, and + `unexpected`. + +C++20 Specific Configuration Macros: ------------------------------------ **_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17**: This macro can be used to disable diagnostics emitted from functions marked ``[[nodiscard]]`` in dialects after C++17. See :ref:`Extended Applications of [[nodiscard]] ` for more information. +**_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES**: + This macro is used to re-enable all the features removed in C++20. The effect + is equivalent to manually defining each macro listed below. + +**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS**: + This macro is used to re-enable redundant members of `allocator`, + including `pointer`, `reference`, `rebind`, `address`, `max_size`, + `construct`, `destroy`, and the two-argument overload of `allocate`. + +**_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**: + This macro is used to re-enable the `argument_type`, `result_type`, + `first_argument_type`, and `second_argument_type` members of class + templates such as `plus`, `logical_not`, `hash`, and `owner_less`. + +**_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS**: + This macro is used to re-enable `not1`, `not2`, `unary_negate`, + and `binary_negate`. + +**_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**: + This macro is used to re-enable `raw_storage_iterator`. + +**_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**: + This macro is used to re-enable `is_literal_type`, `is_literal_type_v`, + `result_of` and `result_of_t`. + Libc++ Extensions ================= @@ -287,15 +278,15 @@ applications of ``[[nodiscard]]`` takes two forms: 1. Backporting ``[[nodiscard]]`` to entities declared as such by the standard in newer dialects, but not in the present one. -2. Extended applications of ``[[nodiscard]]``, at the libraries discretion, +2. Extended applications of ``[[nodiscard]]``, at the library's discretion, applied to entities never declared as such by the standard. Users may also opt-out of additional applications ``[[nodiscard]]`` using additional macros. Applications of the first form, which backport ``[[nodiscard]]`` from a newer -dialect may be disabled using macros specific to the dialect it was added. For -example ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``. +dialect, may be disabled using macros specific to the dialect in which it was +added. For example, ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``. Applications of the second form, which are pure extensions, may be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. @@ -346,3 +337,11 @@ which no dialect declares as such (See the second form described above). * ``unique`` * ``upper_bound`` * ``lock_guard``'s constructors +* ``as_const`` +* ``bit_cast`` +* ``forward`` +* ``move`` +* ``move_if_noexcept`` +* ``identity::operator()`` +* ``to_integer`` +* ``to_underlying`` diff --git a/docs/conf.py b/docs/conf.py index 414f1bc3c..6b0aad6b2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,6 +11,7 @@ # serve to show the default. import sys, os +from datetime import date # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -40,16 +41,16 @@ master_doc = 'index' # General information about the project. project = u'libc++' -copyright = u'2011-2018, LLVM Project' +copyright = u'2011-%d, LLVM Project' % date.today().year # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '10.0' +version = '14.0' # The full version, including alpha/beta/rc tags. -release = '10.0' +release = '14.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -63,7 +64,7 @@ today_fmt = '%Y-%m-%d' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ['_build', 'Helpers'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None diff --git a/docs/index.rst b/docs/index.rst index 04df9cfcc..b1560a51b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,24 +29,35 @@ above. Getting Started with libc++ ---------------------------- +=========================== .. toctree:: - :maxdepth: 2 + :maxdepth: 1 ReleaseNotes UsingLibcxx BuildingLibcxx TestingLibcxx + Contributing + Status/Cxx14 + Status/Cxx17 + Status/Cxx20 + Status/Cxx2b + Status/Format + Status/Ranges + Status/Spaceship + Status/Zip .. toctree:: :hidden: + AddingNewCIJobs FeatureTestMacroTable + Current Status --------------- +============== After its initial introduction, many people have asked "why start a new library instead of contributing to an existing library?" (like Apache's @@ -82,40 +93,62 @@ reasons, but some of the major ones are: Further, both projects are apparently abandoned: STLport 5.2.1 was released in Oct'08, and STDCXX 4.2.1 in May'08. + Platform and Compiler Support ------------------------------ +============================= -libc++ is known to work on the following platforms, using gcc and -clang. -Note that functionality provided by ```` is only functional with clang -and GCC. +Libc++ aims to support common compilers that implement the C++11 Standard. In order to strike a +good balance between stability for users and maintenance cost, testing coverage and development +velocity, libc++ drops support for older compilers as newer ones are released. -============ ==================== ============ ======================== -OS Arch Compilers ABI Library -============ ==================== ============ ======================== -macOS i386, x86_64 Clang, GCC libc++abi -FreeBSD 10+ i386, x86_64, ARM Clang, GCC libcxxrt, libc++abi -Linux i386, x86_64 Clang, GCC libc++abi -============ ==================== ============ ======================== +============ =============== ========================== ===================== +Compiler Versions Restrictions Support policy +============ =============== ========================== ===================== +Clang 12, 13 latest two stable releases per `LLVM's release page `_ +AppleClang 12 latest stable release per `Xcode's release page `_ +Open XL 17.1 (AIX) latest stable release per `Open XL's documentation page `_ +GCC 11 In C++11 or later only latest stable release per `GCC's release page `_ +============ =============== ========================== ===================== -The following minimum compiler versions are strongly recommended. +Libc++ also supports common platforms and architectures: -* Clang 3.5 and above -* GCC 5.0 and above. +=============== ========================= ============================ +Target platform Target architecture Notes +=============== ========================= ============================ +macOS 10.9+ i386, x86_64, arm64 Building the shared library itself requires targetting macOS 10.11+ +FreeBSD 10+ i386, x86_64, arm +Linux i386, x86_64, arm, arm64 +Windows x86_64 Both MSVC and MinGW style environments +AIX powerpc, powerpc64 +=============== ========================= ============================ + +Generally speaking, libc++ should work on any platform that provides a fairly complete +C Standard Library. It is also possible to turn off parts of the library for use on +systems that provide incomplete support. + +However, libc++ aims to provide a high-quality implementation of the C++ Standard +Library, especially when it comes to correctness. As such, we aim to have test coverage +for all the platforms and compilers that we claim to support. If a platform or compiler +is not listed here, it is not officially supported. It may happen to work, and +in practice the library is known to work on some platforms not listed here, but +we don't make any guarantees. If you would like your compiler and/or platform +to be formally supported and listed here, please work with the libc++ team to set +up testing for your configuration. -The C++03 dialect is only supported for Clang compilers. C++ Dialect Support ---------------------- +=================== * C++11 - Complete -* `C++14 - Complete `__ -* `C++17 - In Progress `__ -* `Post C++14 Technical Specifications - In Progress `__ +* :ref:`C++14 - Complete ` +* :ref:`C++17 - In Progress ` +* :ref:`C++20 - In Progress ` +* :ref:`C++2b - In Progress ` * :ref:`C++ Feature Test Macro Status ` + Notes and Known Issues ----------------------- +====================== This list contains known issues with libc++ @@ -125,55 +158,54 @@ This list contains known issues with libc++ A full list of currently open libc++ bugs can be `found here`__. -.. __: https://bugs.llvm.org/buglist.cgi?component=All%20Bugs&product=libc%2B%2B&query_format=advanced&resolution=---&order=changeddate%20DESC%2Cassigned_to%20DESC%2Cbug_status%2Cpriority%2Cbug_id&list_id=74184 +.. __: https://github.com/llvm/llvm-project/labels/libc%2B%2B + Design Documents ----------------- +================ .. toctree:: :maxdepth: 1 - DesignDocs/AvailabilityMarkup - DesignDocs/DebugMode - DesignDocs/CapturingConfigInfo DesignDocs/ABIVersioning + DesignDocs/AtomicDesign + DesignDocs/CapturingConfigInfo + DesignDocs/DebugMode DesignDocs/ExperimentalFeatures - DesignDocs/VisibilityMacros - DesignDocs/ThreadingSupportAPI - DesignDocs/FileTimeType - DesignDocs/FeatureTestMacros DesignDocs/ExtendedCXX03Support + DesignDocs/FeatureTestMacros + DesignDocs/FileTimeType + DesignDocs/NoexceptPolicy + DesignDocs/ThreadingSupportAPI + DesignDocs/UniquePtrTrivialAbi + DesignDocs/UnspecifiedBehaviorRandomization + DesignDocs/VisibilityMacros -* ` design `_ -* ` design `_ -* `Notes by Marshall Clow`__ - -.. __: https://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/ Build Bots and Test Coverage ----------------------------- +============================ + +* `Buildkite CI pipeline `_ +* `LLVM Buildbot Builders `_ +* :ref:`Adding New CI Jobs ` -* `LLVM Buildbot Builders `_ -* `Apple Jenkins Builders `_ -* `Windows Appveyor Builders `_ -* `Code Coverage Results `_ Getting Involved ================ -First please review our `Developer's Policy `__ -and `Getting started with LLVM `__. +First please review our `Developer's Policy `__ +and `Getting started with LLVM `__. **Bug Reports** If you think you've found a bug in libc++, please report it using -the `LLVM Bugzilla`_. If you're not sure, you +the `LLVM bug tracker`_. If you're not sure, you can post a message to the `libcxx-dev mailing list`_ or on IRC. **Patches** If you want to contribute a patch to libc++, the best place for that is -`Phabricator `_. Please add `libcxx-commits` as a subscriber. +`Phabricator `_. Please add `libcxx-commits` as a subscriber. Also make sure you are subscribed to the `libcxx-commits mailing list `_. **Discussion and Questions** @@ -182,12 +214,11 @@ Send discussions and questions to the `libcxx-dev mailing list `_. - Quick Links =========== -* `LLVM Homepage `_ +* `LLVM Homepage `_ * `libc++abi Homepage `_ -* `LLVM Bugzilla `_ +* `LLVM bug tracker `_ * `libcxx-commits Mailing List`_ * `libcxx-dev Mailing List`_ -* `Browse libc++ Sources `_ +* `Browse libc++ Sources `_ diff --git a/fuzzing/RoutineNames.txt b/fuzzing/RoutineNames.txt deleted file mode 100644 index 06ef70ed6..000000000 --- a/fuzzing/RoutineNames.txt +++ /dev/null @@ -1,20 +0,0 @@ -sort -stable_sort -partition -partition_copy -stable_partition -unique -unique_copy -nth_element -partial_sort -partial_sort_copy -make_heap -push_heap -pop_heap -regex_ECMAScript -regex_POSIX -regex_extended -regex_awk -regex_grep -regex_egrep -search diff --git a/fuzzing/fuzz_test.cpp b/fuzzing/fuzz_test.cpp deleted file mode 100644 index 9fa6f4334..000000000 --- a/fuzzing/fuzz_test.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// -*- C++ -*- -//===------------------------- fuzz_test.cpp ------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// A simple program for running regressions on the fuzzing routines. -// This code is not part of any shipping product. -// -// To build: -// clang++ -std=c++11 fuzz_test.cpp fuzzing.cpp -// -// To use: -// fuzz_test -r partial_sort [-v] files... -// -// Each file should contain a test case. - -// TODO: should add some memory tracking, too. - - -#include -#include -#include -#include -#include -#include - -#include "fuzzing.h" - -// ==== Count memory allocations ==== - -struct MemoryCounters { - size_t totalAllocationCount; - size_t netAllocationCount; - size_t totalBytesAllocated; - }; - -MemoryCounters gMemoryCounters; - -void ZeroMemoryCounters() { - gMemoryCounters.totalAllocationCount = 0; - gMemoryCounters.netAllocationCount = 0; - gMemoryCounters.totalBytesAllocated = 0; -} - -void* operator new(std::size_t size) -{ - if (size == 0) size = 1; - void *p = ::malloc(size); - if (p == NULL) - throw std::bad_alloc(); - gMemoryCounters.totalAllocationCount += 1; - gMemoryCounters.netAllocationCount += 1; - gMemoryCounters.totalBytesAllocated += size; - return p; -} - -void* operator new(std::size_t size, const std::nothrow_t&) noexcept -{ - try { return operator new(size); } - catch (const std::bad_alloc &) {} - return nullptr; -} - -void* operator new[](std::size_t size) -{ - return ::operator new(size); -} - -void* operator new[](std::size_t size, const std::nothrow_t&) noexcept -{ - try { return operator new(size); } - catch (const std::bad_alloc &) {} - return nullptr; -} - -void operator delete(void* ptr) noexcept -{ - if (ptr) - ::free(ptr); - gMemoryCounters.netAllocationCount -= 1; -} - -void operator delete(void* ptr, const std::nothrow_t&) noexcept -{ - ::operator delete(ptr); -} - -void operator delete[](void* ptr) noexcept -{ - ::operator delete(ptr); -} - -void operator delete[](void* ptr, const std::nothrow_t&) noexcept -{ - ::operator delete(ptr); -} - -// ==== End count memory allocations ==== - - -typedef int (*FuzzProc) (const uint8_t *data, size_t size); - -const std::map procs = { - {"sort", fuzzing::sort}, - {"stable_sort", fuzzing::stable_sort}, - {"partition", fuzzing::partition}, - {"partition_copy", fuzzing::partition_copy}, - {"stable_partition", fuzzing::stable_partition}, - {"unique", fuzzing::unique}, - {"unique_copy", fuzzing::unique_copy}, - {"nth_element", fuzzing::nth_element}, - {"partial_sort", fuzzing::partial_sort}, - {"partial_sort_copy", fuzzing::partial_sort_copy}, - {"make_heap", fuzzing::make_heap}, - {"push_heap", fuzzing::push_heap}, - {"pop_heap", fuzzing::pop_heap}, - {"regex_ECMAScript", fuzzing::regex_ECMAScript}, - {"regex_POSIX", fuzzing::regex_POSIX}, - {"regex_extended", fuzzing::regex_extended}, - {"regex_awk", fuzzing::regex_awk}, - {"regex_grep", fuzzing::regex_grep}, - {"regex_egrep", fuzzing::regex_egrep}, - {"search", fuzzing::search} -}; - - - -bool verbose = false; - -void test_one(const char *filename, FuzzProc fp) -{ - std::vector v; - std::ifstream f (filename, std::ios::binary); - if (!f.is_open()) - std::cerr << "## Can't open '" << filename << "'" << std::endl; - else - { - typedef std::istream_iterator Iter; - std::copy(Iter(f), Iter(), std::back_inserter(v)); - if (verbose) - std::cout << "File '" << filename << "' contains " << v.size() << " entries" << std::endl; - ZeroMemoryCounters(); - const auto start_time = std::chrono::high_resolution_clock::now(); - int ret = fp (v.data(), v.size()); - const auto finish_time = std::chrono::high_resolution_clock::now(); - MemoryCounters mc = gMemoryCounters; - if (ret != 0) - std::cerr << "## Failure code: " << ret << std::endl; - if (verbose) - { - std::cout << "Execution time: " - << std::chrono::duration_cast(finish_time - start_time).count() - << " milliseconds" << std::endl; - std::cout << "Memory: " - << mc.totalBytesAllocated << " bytes allocated (" - << mc.totalAllocationCount << " allocations); " - << mc.netAllocationCount << " allocations remain" << std::endl; - } - } -} - -void usage (const char *name) -{ - std::cout << "Usage: " << name << " -r proc [-v] files..." << std::endl; - std::cout << "Supported routines:" << std::endl; - for (const auto &p : procs) - std::cout << " " << p.first << std::endl; - std::cout << std::endl; -} - -// Poor man's command-line options -const std::string dashR("-r"); -const std::string dashV("-v"); - -int main(int argc, char *argv[]) -{ - if (argc < 4 || dashR != argv[1] || procs.find(argv[2]) == procs.end()) - usage(argv[0]); - else { - FuzzProc fp = procs.find(argv[2])->second; - int firstFile = 3; - if (dashV == argv[firstFile]) - { - verbose = true; - ++firstFile; - } - for (int i = firstFile; i < argc; ++i) - test_one(argv[i], fp); - } -} diff --git a/fuzzing/fuzzing.cpp b/fuzzing/fuzzing.cpp deleted file mode 100644 index 5c32f28a3..000000000 --- a/fuzzing/fuzzing.cpp +++ /dev/null @@ -1,617 +0,0 @@ -// -*- C++ -*- -//===------------------------- fuzzing.cpp -------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// A set of routines to use when fuzzing the algorithms in libc++ -// Each one tests a single algorithm. -// -// They all have the form of: -// int `algorithm`(const uint8_t *data, size_t size); -// -// They perform the operation, and then check to see if the results are correct. -// If so, they return zero, and non-zero otherwise. -// -// For example, sort calls std::sort, then checks two things: -// (1) The resulting vector is sorted -// (2) The resulting vector contains the same elements as the original data. - - - -#include "fuzzing.h" -#include -#include -#include -#include -#include - -#include - -// If we had C++14, we could use the four iterator version of is_permutation and equal - -namespace fuzzing { - -// This is a struct we can use to test the stable_XXX algorithms. -// perform the operation on the key, then check the order of the payload. - -struct stable_test { - uint8_t key; - size_t payload; - - stable_test(uint8_t k) : key(k), payload(0) {} - stable_test(uint8_t k, size_t p) : key(k), payload(p) {} - }; - -void swap(stable_test &lhs, stable_test &rhs) -{ - using std::swap; - swap(lhs.key, rhs.key); - swap(lhs.payload, rhs.payload); -} - -struct key_less -{ - bool operator () (const stable_test &lhs, const stable_test &rhs) const - { - return lhs.key < rhs.key; - } -}; - -struct payload_less -{ - bool operator () (const stable_test &lhs, const stable_test &rhs) const - { - return lhs.payload < rhs.payload; - } -}; - -struct total_less -{ - bool operator () (const stable_test &lhs, const stable_test &rhs) const - { - return lhs.key == rhs.key ? lhs.payload < rhs.payload : lhs.key < rhs.key; - } -}; - -bool operator==(const stable_test &lhs, const stable_test &rhs) -{ - return lhs.key == rhs.key && lhs.payload == rhs.payload; -} - - -template -struct is_even -{ - bool operator () (const T &t) const - { - return t % 2 == 0; - } -}; - - -template<> -struct is_even -{ - bool operator () (const stable_test &t) const - { - return t.key % 2 == 0; - } -}; - -typedef std::vector Vec; -typedef std::vector StableVec; -typedef StableVec::const_iterator SVIter; - -// Cheap version of is_permutation -// Builds a set of buckets for each of the key values. -// Sums all the payloads. -// Not 100% perfect, but _way_ faster -bool is_permutation(SVIter first1, SVIter last1, SVIter first2) -{ - size_t xBuckets[256] = {0}; - size_t xPayloads[256] = {0}; - size_t yBuckets[256] = {0}; - size_t yPayloads[256] = {0}; - - for (; first1 != last1; ++first1, ++first2) - { - xBuckets [first1->key]++; - xPayloads[first1->key] += first1->payload; - - yBuckets [first2->key]++; - yPayloads[first2->key] += first2->payload; - } - - for (size_t i = 0; i < 256; ++i) - { - if (xBuckets[i] != yBuckets[i]) - return false; - if (xPayloads[i] != yPayloads[i]) - return false; - } - - return true; -} - -template -bool is_permutation(Iter1 first1, Iter1 last1, Iter2 first2) -{ - static_assert((std::is_same::value_type, uint8_t>::value), ""); - static_assert((std::is_same::value_type, uint8_t>::value), ""); - - size_t xBuckets[256] = {0}; - size_t yBuckets[256] = {0}; - - for (; first1 != last1; ++first1, ++first2) - { - xBuckets [*first1]++; - yBuckets [*first2]++; - } - - for (size_t i = 0; i < 256; ++i) - if (xBuckets[i] != yBuckets[i]) - return false; - - return true; -} - -// == sort == -int sort(const uint8_t *data, size_t size) -{ - Vec working(data, data + size); - std::sort(working.begin(), working.end()); - - if (!std::is_sorted(working.begin(), working.end())) return 1; - if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99; - return 0; -} - - -// == stable_sort == -int stable_sort(const uint8_t *data, size_t size) -{ - StableVec input; - for (size_t i = 0; i < size; ++i) - input.push_back(stable_test(data[i], i)); - StableVec working = input; - std::stable_sort(working.begin(), working.end(), key_less()); - - if (!std::is_sorted(working.begin(), working.end(), key_less())) return 1; - auto iter = working.begin(); - while (iter != working.end()) - { - auto range = std::equal_range(iter, working.end(), *iter, key_less()); - if (!std::is_sorted(range.first, range.second, total_less())) return 2; - iter = range.second; - } - if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99; - return 0; -} - -// == partition == -int partition(const uint8_t *data, size_t size) -{ - Vec working(data, data + size); - auto iter = std::partition(working.begin(), working.end(), is_even()); - - if (!std::all_of (working.begin(), iter, is_even())) return 1; - if (!std::none_of(iter, working.end(), is_even())) return 2; - if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99; - return 0; -} - - -// == partition_copy == -int partition_copy(const uint8_t *data, size_t size) -{ - Vec v1, v2; - auto iter = std::partition_copy(data, data + size, - std::back_inserter(v1), std::back_inserter(v2), - is_even()); - -// The two vectors should add up to the original size - if (v1.size() + v2.size() != size) return 1; - -// All of the even values should be in the first vector, and none in the second - if (!std::all_of (v1.begin(), v1.end(), is_even())) return 2; - if (!std::none_of(v2.begin(), v2.end(), is_even())) return 3; - -// Every value in both vectors has to be in the original - -// Make a copy of the input, and sort it - Vec v0{data, data + size}; - std::sort(v0.begin(), v0.end()); - -// Sort each vector and ensure that all of the elements appear in the original input - std::sort(v1.begin(), v1.end()); - if (!std::includes(v0.begin(), v0.end(), v1.begin(), v1.end())) return 4; - - std::sort(v2.begin(), v2.end()); - if (!std::includes(v0.begin(), v0.end(), v2.begin(), v2.end())) return 5; - -// This, while simple, is really slow - 20 seconds on a 500K element input. -// for (auto v: v1) -// if (std::find(data, data + size, v) == data + size) return 4; -// -// for (auto v: v2) -// if (std::find(data, data + size, v) == data + size) return 5; - - return 0; -} - -// == stable_partition == -int stable_partition (const uint8_t *data, size_t size) -{ - StableVec input; - for (size_t i = 0; i < size; ++i) - input.push_back(stable_test(data[i], i)); - StableVec working = input; - auto iter = std::stable_partition(working.begin(), working.end(), is_even()); - - if (!std::all_of (working.begin(), iter, is_even())) return 1; - if (!std::none_of(iter, working.end(), is_even())) return 2; - if (!std::is_sorted(working.begin(), iter, payload_less())) return 3; - if (!std::is_sorted(iter, working.end(), payload_less())) return 4; - if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99; - return 0; -} - -// == nth_element == -// use the first element as a position into the data -int nth_element (const uint8_t *data, size_t size) -{ - if (size <= 1) return 0; - const size_t partition_point = data[0] % size; - Vec working(data + 1, data + size); - const auto partition_iter = working.begin() + partition_point; - std::nth_element(working.begin(), partition_iter, working.end()); - -// nth may be the end iterator, in this case nth_element has no effect. - if (partition_iter == working.end()) - { - if (!std::equal(data + 1, data + size, working.begin())) return 98; - } - else - { - const uint8_t nth = *partition_iter; - if (!std::all_of(working.begin(), partition_iter, [=](uint8_t v) { return v <= nth; })) - return 1; - if (!std::all_of(partition_iter, working.end(), [=](uint8_t v) { return v >= nth; })) - return 2; - if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99; - } - - return 0; -} - -// == partial_sort == -// use the first element as a position into the data -int partial_sort (const uint8_t *data, size_t size) -{ - if (size <= 1) return 0; - const size_t sort_point = data[0] % size; - Vec working(data + 1, data + size); - const auto sort_iter = working.begin() + sort_point; - std::partial_sort(working.begin(), sort_iter, working.end()); - - if (sort_iter != working.end()) - { - const uint8_t nth = *std::min_element(sort_iter, working.end()); - if (!std::all_of(working.begin(), sort_iter, [=](uint8_t v) { return v <= nth; })) - return 1; - if (!std::all_of(sort_iter, working.end(), [=](uint8_t v) { return v >= nth; })) - return 2; - } - if (!std::is_sorted(working.begin(), sort_iter)) return 3; - if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99; - - return 0; -} - - -// == partial_sort_copy == -// use the first element as a count -int partial_sort_copy (const uint8_t *data, size_t size) -{ - if (size <= 1) return 0; - const size_t num_results = data[0] % size; - Vec results(num_results); - (void) std::partial_sort_copy(data + 1, data + size, results.begin(), results.end()); - -// The results have to be sorted - if (!std::is_sorted(results.begin(), results.end())) return 1; -// All the values in results have to be in the original data - for (auto v: results) - if (std::find(data + 1, data + size, v) == data + size) return 2; - -// The things in results have to be the smallest N in the original data - Vec sorted(data + 1, data + size); - std::sort(sorted.begin(), sorted.end()); - if (!std::equal(results.begin(), results.end(), sorted.begin())) return 3; - return 0; -} - -// The second sequence has been "uniqued" -template -static bool compare_unique(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) -{ - assert(first1 != last1 && first2 != last2); - if (*first1 != *first2) return false; - - uint8_t last_value = *first1; - ++first1; ++first2; - while(first1 != last1 && first2 != last2) - { - // Skip over dups in the first sequence - while (*first1 == last_value) - if (++first1 == last1) return false; - if (*first1 != *first2) return false; - last_value = *first1; - ++first1; ++first2; - } - -// Still stuff left in the 'uniqued' sequence - oops - if (first1 == last1 && first2 != last2) return false; - -// Still stuff left in the original sequence - better be all the same - while (first1 != last1) - { - if (*first1 != last_value) return false; - ++first1; - } - return true; -} - -// == unique == -int unique (const uint8_t *data, size_t size) -{ - Vec working(data, data + size); - std::sort(working.begin(), working.end()); - Vec results = working; - Vec::iterator new_end = std::unique(results.begin(), results.end()); - Vec::iterator it; // scratch iterator - -// Check the size of the unique'd sequence. -// it should only be zero if the input sequence was empty. - if (results.begin() == new_end) - return working.size() == 0 ? 0 : 1; - -// 'results' is sorted - if (!std::is_sorted(results.begin(), new_end)) return 2; - -// All the elements in 'results' must be different - it = results.begin(); - uint8_t prev_value = *it++; - for (; it != new_end; ++it) - { - if (*it == prev_value) return 3; - prev_value = *it; - } - -// Every element in 'results' must be in 'working' - for (it = results.begin(); it != new_end; ++it) - if (std::find(working.begin(), working.end(), *it) == working.end()) - return 4; - -// Every element in 'working' must be in 'results' - for (auto v : working) - if (std::find(results.begin(), new_end, v) == new_end) - return 5; - - return 0; -} - -// == unique_copy == -int unique_copy (const uint8_t *data, size_t size) -{ - Vec working(data, data + size); - std::sort(working.begin(), working.end()); - Vec results; - (void) std::unique_copy(working.begin(), working.end(), - std::back_inserter(results)); - Vec::iterator it; // scratch iterator - -// Check the size of the unique'd sequence. -// it should only be zero if the input sequence was empty. - if (results.size() == 0) - return working.size() == 0 ? 0 : 1; - -// 'results' is sorted - if (!std::is_sorted(results.begin(), results.end())) return 2; - -// All the elements in 'results' must be different - it = results.begin(); - uint8_t prev_value = *it++; - for (; it != results.end(); ++it) - { - if (*it == prev_value) return 3; - prev_value = *it; - } - -// Every element in 'results' must be in 'working' - for (auto v : results) - if (std::find(working.begin(), working.end(), v) == working.end()) - return 4; - -// Every element in 'working' must be in 'results' - for (auto v : working) - if (std::find(results.begin(), results.end(), v) == results.end()) - return 5; - - return 0; -} - - -// -- regex fuzzers -static int regex_helper(const uint8_t *data, size_t size, std::regex::flag_type flag) -{ - if (size > 0) - { - try - { - std::string s((const char *)data, size); - std::regex re(s, flag); - return std::regex_match(s, re) ? 1 : 0; - } - catch (std::regex_error &ex) {} - } - return 0; -} - - -int regex_ECMAScript (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::ECMAScript); - return 0; -} - -int regex_POSIX (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::basic); - return 0; -} - -int regex_extended (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::extended); - return 0; -} - -int regex_awk (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::awk); - return 0; -} - -int regex_grep (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::grep); - return 0; -} - -int regex_egrep (const uint8_t *data, size_t size) -{ - (void) regex_helper(data, size, std::regex_constants::egrep); - return 0; -} - -// -- heap fuzzers -int make_heap (const uint8_t *data, size_t size) -{ - Vec working(data, data + size); - std::make_heap(working.begin(), working.end()); - - if (!std::is_heap(working.begin(), working.end())) return 1; - if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99; - return 0; -} - -int push_heap (const uint8_t *data, size_t size) -{ - if (size < 2) return 0; - -// Make a heap from the first half of the data - Vec working(data, data + size); - auto iter = working.begin() + (size / 2); - std::make_heap(working.begin(), iter); - if (!std::is_heap(working.begin(), iter)) return 1; - -// Now push the rest onto the heap, one at a time - ++iter; - for (; iter != working.end(); ++iter) { - std::push_heap(working.begin(), iter); - if (!std::is_heap(working.begin(), iter)) return 2; - } - - if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99; - return 0; -} - -int pop_heap (const uint8_t *data, size_t size) -{ - if (size < 2) return 0; - Vec working(data, data + size); - std::make_heap(working.begin(), working.end()); - -// Pop things off, one at a time - auto iter = --working.end(); - while (iter != working.begin()) { - std::pop_heap(working.begin(), iter); - if (!std::is_heap(working.begin(), --iter)) return 2; - } - - return 0; -} - - -// -- search fuzzers -int search (const uint8_t *data, size_t size) -{ - if (size < 2) return 0; - - const size_t pat_size = data[0] * (size - 1) / std::numeric_limits::max(); - assert(pat_size <= size - 1); - const uint8_t *pat_begin = data + 1; - const uint8_t *pat_end = pat_begin + pat_size; - const uint8_t *data_end = data + size; - assert(pat_end <= data_end); -// std::cerr << "data[0] = " << size_t(data[0]) << " "; -// std::cerr << "Pattern size = " << pat_size << "; corpus is " << size - 1 << std::endl; - auto it = std::search(pat_end, data_end, pat_begin, pat_end); - if (it != data_end) // not found - if (!std::equal(pat_begin, pat_end, it)) - return 1; - return 0; -} - -template -static int search_helper (const uint8_t *data, size_t size) -{ - if (size < 2) return 0; - - const size_t pat_size = data[0] * (size - 1) / std::numeric_limits::max(); - const uint8_t *pat_begin = data + 1; - const uint8_t *pat_end = pat_begin + pat_size; - const uint8_t *data_end = data + size; - - auto it = std::search(pat_end, data_end, S(pat_begin, pat_end)); - if (it != data_end) // not found - if (!std::equal(pat_begin, pat_end, it)) - return 1; - return 0; -} - -// These are still in std::experimental -// int search_boyer_moore (const uint8_t *data, size_t size) -// { -// return search_helper>(data, size); -// } -// -// int search_boyer_moore_horspool (const uint8_t *data, size_t size) -// { -// return search_helper>(data, size); -// } - - -// -- set operation fuzzers -template -static void set_helper (const uint8_t *data, size_t size, Vec &v1, Vec &v2) -{ - assert(size > 1); - - const size_t pat_size = data[0] * (size - 1) / std::numeric_limits::max(); - const uint8_t *pat_begin = data + 1; - const uint8_t *pat_end = pat_begin + pat_size; - const uint8_t *data_end = data + size; - v1.assign(pat_begin, pat_end); - v2.assign(pat_end, data_end); - - std::sort(v1.begin(), v1.end()); - std::sort(v2.begin(), v2.end()); -} - -} // namespace fuzzing diff --git a/fuzzing/fuzzing.h b/fuzzing/fuzzing.h deleted file mode 100644 index 64103e590..000000000 --- a/fuzzing/fuzzing.h +++ /dev/null @@ -1,61 +0,0 @@ -// -*- C++ -*- -//===-------------------------- fuzzing.h --------------------------------===// -// -// 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_FUZZING -#define _LIBCPP_FUZZING - -#include // for size_t -#include // for uint8_t - -namespace fuzzing { - -// These all return 0 on success; != 0 on failure - int sort (const uint8_t *data, size_t size); - int stable_sort (const uint8_t *data, size_t size); - int partition (const uint8_t *data, size_t size); - int partition_copy (const uint8_t *data, size_t size); - int stable_partition (const uint8_t *data, size_t size); - int unique (const uint8_t *data, size_t size); - int unique_copy (const uint8_t *data, size_t size); - -// partition and stable_partition take Bi-Di iterators. -// Should test those, too - int nth_element (const uint8_t *data, size_t size); - int partial_sort (const uint8_t *data, size_t size); - int partial_sort_copy (const uint8_t *data, size_t size); - -// Heap operations - int make_heap (const uint8_t *data, size_t size); - int push_heap (const uint8_t *data, size_t size); - int pop_heap (const uint8_t *data, size_t size); - -// Various flavors of regex - int regex_ECMAScript (const uint8_t *data, size_t size); - int regex_POSIX (const uint8_t *data, size_t size); - int regex_extended (const uint8_t *data, size_t size); - int regex_awk (const uint8_t *data, size_t size); - int regex_grep (const uint8_t *data, size_t size); - int regex_egrep (const uint8_t *data, size_t size); - -// Searching - int search (const uint8_t *data, size_t size); -// int search_boyer_moore (const uint8_t *data, size_t size); -// int search_boyer_moore_horspool (const uint8_t *data, size_t size); - -// Set operations -// int includes (const uint8_t *data, size_t size); -// int set_union (const uint8_t *data, size_t size); -// int set_intersection (const uint8_t *data, size_t size); -// int set_difference (const uint8_t *data, size_t size); -// int set_symmetric_difference (const uint8_t *data, size_t size); -// int merge (const uint8_t *data, size_t size); - -} // namespace fuzzing - -#endif // _LIBCPP_FUZZING diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 302da8a13..53700fc9e 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,30 +1,406 @@ set(files + __algorithm/adjacent_find.h + __algorithm/all_of.h + __algorithm/any_of.h + __algorithm/binary_search.h + __algorithm/clamp.h + __algorithm/comp.h + __algorithm/comp_ref_type.h + __algorithm/copy.h + __algorithm/copy_backward.h + __algorithm/copy_if.h + __algorithm/copy_n.h + __algorithm/count.h + __algorithm/count_if.h + __algorithm/equal.h + __algorithm/equal_range.h + __algorithm/fill.h + __algorithm/fill_n.h + __algorithm/find.h + __algorithm/find_end.h + __algorithm/find_first_of.h + __algorithm/find_if.h + __algorithm/find_if_not.h + __algorithm/for_each.h + __algorithm/for_each_n.h + __algorithm/generate.h + __algorithm/generate_n.h + __algorithm/half_positive.h + __algorithm/in_in_out_result.h + __algorithm/in_in_result.h + __algorithm/in_out_result.h + __algorithm/includes.h + __algorithm/inplace_merge.h + __algorithm/is_heap.h + __algorithm/is_heap_until.h + __algorithm/is_partitioned.h + __algorithm/is_permutation.h + __algorithm/is_sorted.h + __algorithm/is_sorted_until.h + __algorithm/iter_swap.h + __algorithm/lexicographical_compare.h + __algorithm/lower_bound.h + __algorithm/make_heap.h + __algorithm/max.h + __algorithm/max_element.h + __algorithm/merge.h + __algorithm/min.h + __algorithm/min_element.h + __algorithm/minmax.h + __algorithm/minmax_element.h + __algorithm/mismatch.h + __algorithm/move.h + __algorithm/move_backward.h + __algorithm/next_permutation.h + __algorithm/none_of.h + __algorithm/nth_element.h + __algorithm/partial_sort.h + __algorithm/partial_sort_copy.h + __algorithm/partition.h + __algorithm/partition_copy.h + __algorithm/partition_point.h + __algorithm/pop_heap.h + __algorithm/prev_permutation.h + __algorithm/push_heap.h + __algorithm/remove.h + __algorithm/remove_copy.h + __algorithm/remove_copy_if.h + __algorithm/remove_if.h + __algorithm/replace.h + __algorithm/replace_copy.h + __algorithm/replace_copy_if.h + __algorithm/replace_if.h + __algorithm/reverse.h + __algorithm/reverse_copy.h + __algorithm/rotate.h + __algorithm/rotate_copy.h + __algorithm/sample.h + __algorithm/search.h + __algorithm/search_n.h + __algorithm/set_difference.h + __algorithm/set_intersection.h + __algorithm/set_symmetric_difference.h + __algorithm/set_union.h + __algorithm/shift_left.h + __algorithm/shift_right.h + __algorithm/shuffle.h + __algorithm/sift_down.h + __algorithm/sort.h + __algorithm/sort_heap.h + __algorithm/stable_partition.h + __algorithm/stable_sort.h + __algorithm/swap_ranges.h + __algorithm/transform.h + __algorithm/unique.h + __algorithm/unique_copy.h + __algorithm/unwrap_iter.h + __algorithm/upper_bound.h + __availability + __bit/bit_cast.h + __bit/byteswap.h __bit_reference + __bits __bsd_locale_defaults.h __bsd_locale_fallbacks.h - __errc + __charconv/chars_format.h + __charconv/from_chars_result.h + __charconv/to_chars_result.h + __chrono/calendar.h + __chrono/convert_to_timespec.h + __chrono/duration.h + __chrono/file_clock.h + __chrono/high_resolution_clock.h + __chrono/steady_clock.h + __chrono/system_clock.h + __chrono/time_point.h + __compare/common_comparison_category.h + __compare/compare_partial_order_fallback.h + __compare/compare_strong_order_fallback.h + __compare/compare_three_way.h + __compare/compare_three_way_result.h + __compare/compare_weak_order_fallback.h + __compare/is_eq.h + __compare/ordering.h + __compare/partial_order.h + __compare/strong_order.h + __compare/synth_three_way.h + __compare/three_way_comparable.h + __compare/weak_order.h + __concepts/arithmetic.h + __concepts/assignable.h + __concepts/boolean_testable.h + __concepts/class_or_enum.h + __concepts/common_reference_with.h + __concepts/common_with.h + __concepts/constructible.h + __concepts/convertible_to.h + __concepts/copyable.h + __concepts/derived_from.h + __concepts/destructible.h + __concepts/different_from.h + __concepts/equality_comparable.h + __concepts/invocable.h + __concepts/movable.h + __concepts/predicate.h + __concepts/regular.h + __concepts/relation.h + __concepts/same_as.h + __concepts/semiregular.h + __concepts/swappable.h + __concepts/totally_ordered.h + __config + __coroutine/coroutine_handle.h + __coroutine/coroutine_traits.h + __coroutine/noop_coroutine_handle.h + __coroutine/trivial_awaitables.h __debug - __functional_03 + __errc + __filesystem/copy_options.h + __filesystem/directory_entry.h + __filesystem/directory_iterator.h + __filesystem/directory_options.h + __filesystem/file_status.h + __filesystem/file_time_type.h + __filesystem/file_type.h + __filesystem/filesystem_error.h + __filesystem/operations.h + __filesystem/path.h + __filesystem/path_iterator.h + __filesystem/perm_options.h + __filesystem/perms.h + __filesystem/recursive_directory_iterator.h + __filesystem/space_info.h + __filesystem/u8path.h + __format/format_arg.h + __format/format_args.h + __format/format_context.h + __format/format_error.h + __format/format_fwd.h + __format/format_parse_context.h + __format/format_string.h + __format/format_to_n_result.h + __format/formatter.h + __format/formatter_bool.h + __format/formatter_char.h + __format/formatter_floating_point.h + __format/formatter_integer.h + __format/formatter_integral.h + __format/formatter_pointer.h + __format/formatter_string.h + __format/parser_std_format_spec.h + __functional/binary_function.h + __functional/binary_negate.h + __functional/bind.h + __functional/bind_back.h + __functional/bind_front.h + __functional/binder1st.h + __functional/binder2nd.h + __functional/compose.h + __functional/default_searcher.h + __functional/function.h + __functional/hash.h + __functional/identity.h + __functional/invoke.h + __functional/is_transparent.h + __functional/mem_fn.h + __functional/mem_fun_ref.h + __functional/not_fn.h + __functional/operations.h + __functional/perfect_forward.h + __functional/pointer_to_binary_function.h + __functional/pointer_to_unary_function.h + __functional/ranges_operations.h + __functional/reference_wrapper.h + __functional/unary_function.h + __functional/unary_negate.h + __functional/unwrap_ref.h + __functional/weak_result_type.h __functional_base - __functional_base_03 __hash_table + __iterator/access.h + __iterator/advance.h + __iterator/back_insert_iterator.h + __iterator/common_iterator.h + __iterator/concepts.h + __iterator/counted_iterator.h + __iterator/data.h + __iterator/default_sentinel.h + __iterator/distance.h + __iterator/empty.h + __iterator/erase_if_container.h + __iterator/front_insert_iterator.h + __iterator/incrementable_traits.h + __iterator/indirectly_comparable.h + __iterator/insert_iterator.h + __iterator/istream_iterator.h + __iterator/istreambuf_iterator.h + __iterator/iter_move.h + __iterator/iter_swap.h + __iterator/iterator.h + __iterator/iterator_traits.h + __iterator/move_iterator.h + __iterator/next.h + __iterator/ostream_iterator.h + __iterator/ostreambuf_iterator.h + __iterator/prev.h + __iterator/projected.h + __iterator/readable_traits.h + __iterator/reverse_access.h + __iterator/reverse_iterator.h + __iterator/size.h + __iterator/unreachable_sentinel.h + __iterator/wrap_iter.h __libcpp_version __locale + __mbstate_t.h + __memory/addressof.h + __memory/allocation_guard.h + __memory/allocator.h + __memory/allocator_arg_t.h + __memory/allocator_traits.h + __memory/auto_ptr.h + __memory/compressed_pair.h + __memory/concepts.h + __memory/construct_at.h + __memory/pointer_traits.h + __memory/ranges_construct_at.h + __memory/ranges_uninitialized_algorithms.h + __memory/raw_storage_iterator.h + __memory/shared_ptr.h + __memory/temporary_buffer.h + __memory/uninitialized_algorithms.h + __memory/unique_ptr.h + __memory/uses_allocator.h + __memory/voidify.h __mutex_base __node_handle __nullptr + __numeric/accumulate.h + __numeric/adjacent_difference.h + __numeric/exclusive_scan.h + __numeric/gcd_lcm.h + __numeric/inclusive_scan.h + __numeric/inner_product.h + __numeric/iota.h + __numeric/midpoint.h + __numeric/partial_sum.h + __numeric/reduce.h + __numeric/transform_exclusive_scan.h + __numeric/transform_inclusive_scan.h + __numeric/transform_reduce.h + __random/bernoulli_distribution.h + __random/binomial_distribution.h + __random/cauchy_distribution.h + __random/chi_squared_distribution.h + __random/clamp_to_integral.h + __random/default_random_engine.h + __random/discard_block_engine.h + __random/discrete_distribution.h + __random/exponential_distribution.h + __random/extreme_value_distribution.h + __random/fisher_f_distribution.h + __random/gamma_distribution.h + __random/generate_canonical.h + __random/geometric_distribution.h + __random/independent_bits_engine.h + __random/is_seed_sequence.h + __random/knuth_b.h + __random/linear_congruential_engine.h + __random/log2.h + __random/lognormal_distribution.h + __random/mersenne_twister_engine.h + __random/negative_binomial_distribution.h + __random/normal_distribution.h + __random/piecewise_constant_distribution.h + __random/piecewise_linear_distribution.h + __random/poisson_distribution.h + __random/random_device.h + __random/ranlux.h + __random/seed_seq.h + __random/shuffle_order_engine.h + __random/student_t_distribution.h + __random/subtract_with_carry_engine.h + __random/uniform_int_distribution.h + __random/uniform_random_bit_generator.h + __random/uniform_real_distribution.h + __random/weibull_distribution.h + __ranges/access.h + __ranges/all.h + __ranges/common_view.h + __ranges/concepts.h + __ranges/copyable_box.h + __ranges/counted.h + __ranges/dangling.h + __ranges/data.h + __ranges/drop_view.h + __ranges/empty.h + __ranges/empty_view.h + __ranges/enable_borrowed_range.h + __ranges/enable_view.h + __ranges/iota_view.h + __ranges/join_view.h + __ranges/non_propagating_cache.h + __ranges/owning_view.h + __ranges/range_adaptor.h + __ranges/ref_view.h + __ranges/reverse_view.h + __ranges/single_view.h + __ranges/size.h + __ranges/subrange.h + __ranges/take_view.h + __ranges/transform_view.h + __ranges/view_interface.h + __ranges/views.h __split_buffer - __sso_allocator __std_stream __string + __support/android/locale_bionic.h + __support/fuchsia/xlocale.h + __support/ibm/gettod_zos.h + __support/ibm/limits.h + __support/ibm/locale_mgmt_zos.h + __support/ibm/nanosleep.h + __support/ibm/support.h + __support/ibm/xlocale.h + __support/musl/xlocale.h + __support/newlib/xlocale.h + __support/openbsd/xlocale.h + __support/solaris/floatingpoint.h + __support/solaris/wchar.h + __support/solaris/xlocale.h + __support/win32/limits_msvc_win32.h + __support/win32/locale_win32.h + __support/xlocale/__nop_locale_mgmt.h + __support/xlocale/__posix_l_fallback.h + __support/xlocale/__strtonum_fallback.h + __thread/poll_with_backoff.h + __thread/timed_backoff_policy.h __threading_support __tree __tuple __undef_macros + __utility/as_const.h + __utility/auto_cast.h + __utility/cmp.h + __utility/declval.h + __utility/exchange.h + __utility/forward.h + __utility/in_place.h + __utility/integer_sequence.h + __utility/move.h + __utility/pair.h + __utility/piecewise_construct.h + __utility/priority_tag.h + __utility/rel_ops.h + __utility/swap.h + __utility/to_underlying.h + __utility/transaction.h + __variant/monostate.h algorithm any array atomic + barrier bit bitset cassert @@ -44,7 +420,9 @@ set(files compare complex complex.h + concepts condition_variable + coroutine csetjmp csignal cstdarg @@ -91,6 +469,7 @@ set(files fenv.h filesystem float.h + format forward_list fstream functional @@ -103,6 +482,7 @@ set(files iostream istream iterator + latch limits limits.h list @@ -114,14 +494,17 @@ set(files module.modulemap mutex new + numbers numeric optional ostream queue random + ranges ratio regex scoped_allocator + semaphore set setjmp.h shared_mutex @@ -157,118 +540,55 @@ set(files wctype.h ) -if(LIBCXX_INSTALL_SUPPORT_HEADERS) - set(files - ${files} - support/android/locale_bionic.h - support/fuchsia/xlocale.h - support/ibm/limits.h - support/ibm/locale_mgmt_aix.h - support/ibm/support.h - support/ibm/xlocale.h - support/musl/xlocale.h - support/newlib/xlocale.h - support/solaris/floatingpoint.h - support/solaris/wchar.h - support/solaris/xlocale.h - support/win32/limits_msvc_win32.h - support/win32/locale_win32.h - support/xlocale/__nop_locale_mgmt.h - support/xlocale/__posix_l_fallback.h - support/xlocale/__strtonum_fallback.h - ) -endif() +configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" @ONLY) -if (LIBCXX_NEEDS_SITE_CONFIG) - # Generate a custom __config header. The new header is created - # by prepending __config_site to the current __config header. - add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config - COMMAND ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/cat_files.py - ${LIBCXX_BINARY_DIR}/__config_site - ${LIBCXX_SOURCE_DIR}/include/__config - -o ${LIBCXX_BINARY_DIR}/__generated_config - DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config - ${LIBCXX_BINARY_DIR}/__config_site - ) - # Add a target that executes the generation commands. - add_custom_target(cxx-generated-config ALL - DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config) - set(generated_config_deps cxx-generated-config) +set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site") +foreach(f ${files}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}") + set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}") + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying CXX header ${f}") + list(APPEND _all_includes "${dst}") +endforeach() + +add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes}) + +add_library(cxx-headers INTERFACE) +add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET}) +# TODO: Use target_include_directories once we figure out why that breaks the runtimes build +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") + target_compile_options(cxx-headers INTERFACE /I${LIBCXX_GENERATED_INCLUDE_DIR} + INTERFACE /I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) else() - set(files - ${files} - __config - ) + target_compile_options(cxx-headers INTERFACE -I${LIBCXX_GENERATED_INCLUDE_DIR} + INTERFACE -I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) endif() -# In some build configurations (like bootstrapping clang), we need to be able to -# install the libcxx headers before the CMake configuration for libcxx runs. Making -# the name of this target configurable allows LLVM/runtimes/CMakeLists.txt to -# add this subdirectory to the LLVM build to put libcxx's headers in place -# before libcxx's build configuration is run. -if (NOT CXX_HEADER_TARGET) - set(CXX_HEADER_TARGET cxx-headers) -endif() -if(NOT LIBCXX_USING_INSTALLED_LLVM AND LIBCXX_HEADER_DIR) - set(output_dir ${LIBCXX_HEADER_DIR}/include/c++/v1) - - set(out_files) - foreach(f ${files}) - set(src ${CMAKE_CURRENT_SOURCE_DIR}/${f}) - set(dst ${output_dir}/${f}) - add_custom_command(OUTPUT ${dst} - DEPENDS ${src} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying CXX header ${f}") - list(APPEND out_files ${dst}) - endforeach() - - if (LIBCXX_NEEDS_SITE_CONFIG) - # Copy the generated header as __config into build directory. - set(src ${LIBCXX_BINARY_DIR}/__generated_config) - set(dst ${output_dir}/__config) - add_custom_command(OUTPUT ${dst} - DEPENDS ${src} ${generated_config_deps} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying CXX __config") - list(APPEND out_files ${dst}) - endif() - - add_custom_target(${CXX_HEADER_TARGET} ALL DEPENDS ${out_files} ${LIBCXX_CXX_ABI_HEADER_TARGET}) -else() - add_custom_target(${CXX_HEADER_TARGET}) -endif() -set_target_properties(${CXX_HEADER_TARGET} PROPERTIES FOLDER "Misc") - if (LIBCXX_INSTALL_HEADERS) foreach(file ${files}) get_filename_component(dir ${file} DIRECTORY) install(FILES ${file} - DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dir} - COMPONENT ${CXX_HEADER_TARGET} + DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}/${dir}" + COMPONENT cxx-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endforeach() - if (LIBCXX_NEEDS_SITE_CONFIG) - # Install the generated header as __config. - install(FILES ${LIBCXX_BINARY_DIR}/__generated_config - DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1 - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - RENAME __config - COMPONENT ${CXX_HEADER_TARGET}) - endif() + # Install the generated __config_site. + install(FILES ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site + DESTINATION "${LIBCXX_INSTALL_INCLUDE_TARGET_DIR}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT cxx-headers) if (NOT CMAKE_CONFIGURATION_TYPES) - add_custom_target(install-${CXX_HEADER_TARGET} - DEPENDS ${CXX_HEADER_TARGET} ${generated_config_deps} + add_custom_target(install-cxx-headers + DEPENDS cxx-headers COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=${CXX_HEADER_TARGET} + -DCMAKE_INSTALL_COMPONENT=cxx-headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") # Stripping is a no-op for headers - add_custom_target(install-${CXX_HEADER_TARGET}-stripped DEPENDS install-${CXX_HEADER_TARGET}) - - add_custom_target(install-libcxx-headers DEPENDS install-${CXX_HEADER_TARGET}) - add_custom_target(install-libcxx-headers-stripped DEPENDS install-${CXX_HEADER_TARGET}-stripped) + add_custom_target(install-cxx-headers-stripped DEPENDS install-cxx-headers) endif() endif() diff --git a/include/__algorithm/adjacent_find.h b/include/__algorithm/adjacent_find.h new file mode 100644 index 000000000..29ad83f96 --- /dev/null +++ b/include/__algorithm/adjacent_find.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___ALGORITHM_ADJACENT_FIND_H +#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (__pred(*__first, *__i)) + return __first; + __first = __i; + } + } + return __last; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H diff --git a/include/__algorithm/all_of.h b/include/__algorithm/all_of.h new file mode 100644 index 000000000..817a4bc89 --- /dev/null +++ b/include/__algorithm/all_of.h @@ -0,0 +1,32 @@ +// -*- 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_ALL_OF_H +#define _LIBCPP___ALGORITHM_ALL_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ALL_OF_H diff --git a/include/__algorithm/any_of.h b/include/__algorithm/any_of.h new file mode 100644 index 000000000..f4116d913 --- /dev/null +++ b/include/__algorithm/any_of.h @@ -0,0 +1,32 @@ +// -*- 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_ANY_OF_H +#define _LIBCPP___ALGORITHM_ANY_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return true; + return false; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ANY_OF_H diff --git a/include/__algorithm/binary_search.h b/include/__algorithm/binary_search.h new file mode 100644 index 000000000..2558dd0b2 --- /dev/null +++ b/include/__algorithm/binary_search.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___ALGORITHM_BINARY_SEARCH_H +#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +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 +_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); +} + +template +_LIBCPP_NODISCARD_EXT inline +_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::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H diff --git a/include/__algorithm/clamp.h b/include/__algorithm/clamp.h new file mode 100644 index 000000000..a51c1015b --- /dev/null +++ b/include/__algorithm/clamp.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_CLAMP_H +#define _LIBCPP___ALGORITHM_CLAMP_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) +{ + _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; + +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) +{ + return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_CLAMP_H diff --git a/include/__algorithm/comp.h b/include/__algorithm/comp.h new file mode 100644 index 000000000..b3f971e4f --- /dev/null +++ b/include/__algorithm/comp.h @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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_COMP_H +#define _LIBCPP___ALGORITHM_COMP_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// I'd like to replace these with _VSTD::equal_to, but can't because: +// * That only works with C++14 and later, and +// * We haven't included here. +template +struct __equal_to +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} +}; + +template +struct __equal_to<_T1, _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __equal_to +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __equal_to<_T1, const _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +template +struct __less<_T1, const _T1> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COMP_H diff --git a/include/__algorithm/comp_ref_type.h b/include/__algorithm/comp_ref_type.h new file mode 100644 index 000000000..0802d2496 --- /dev/null +++ b/include/__algorithm/comp_ref_type.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_COMP_REF_TYPE_H +#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H + +#include <__config> + +#ifdef _LIBCPP_DEBUG +# include <__debug> +# include <__utility/declval.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_DEBUG + +template +struct __debug_less +{ + _Compare &__comp_; + _LIBCPP_CONSTEXPR_AFTER_CXX11 + __debug_less(_Compare& __c) : __comp_(__c) {} + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _Tp& __x, const _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(_Tp& __x, _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } + + template + _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), + "Comparator does not induce a strict weak ordering"); + } + + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 + inline _LIBCPP_INLINE_VISIBILITY + void __do_compare_assert(long, _LHS &, _RHS &) {} +}; + +#endif // _LIBCPP_DEBUG + +template +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 + typedef __debug_less<_Comp> type; +#endif +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H diff --git a/include/__algorithm/copy.h b/include/__algorithm/copy.h new file mode 100644 index 000000000..65f0e0b0e --- /dev/null +++ b/include/__algorithm/copy.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_COPY_H +#define _LIBCPP___ALGORITHM_COPY_H + +#include <__algorithm/unwrap_iter.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// copy + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return _VSTD::__copy_constexpr(__first, __last, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_copy_assignable<_Up>::value, + _Up* +>::type +__copy(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + return __result + __n; +} + +template +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))); + } +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_H diff --git a/include/__algorithm/copy_backward.h b/include/__algorithm/copy_backward.h new file mode 100644 index 000000000..ac733290a --- /dev/null +++ b/include/__algorithm/copy_backward.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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_COPY_BACKWARD_H +#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H + +#include <__algorithm/unwrap_iter.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +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 +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + return _VSTD::__copy_backward_constexpr(__first, __last, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_same::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(__last - __first); + if (__n > 0) + { + __result -= __n; + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _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))); + } +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H diff --git a/include/__algorithm/copy_if.h b/include/__algorithm/copy_if.h new file mode 100644 index 000000000..d32514d99 --- /dev/null +++ b/include/__algorithm/copy_if.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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_COPY_IF_H +#define _LIBCPP___ALGORITHM_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_IF_H diff --git a/include/__algorithm/copy_n.h b/include/__algorithm/copy_n.h new file mode 100644 index 000000000..cdcc0d50d --- /dev/null +++ b/include/__algorithm/copy_n.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_COPY_N_H +#define _LIBCPP___ALGORITHM_COPY_N_H + +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +typename enable_if +< + __is_cpp17_input_iterator<_InputIterator>::value && + !__is_cpp17_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + if (__n > 0) + { + *__result = *__first; + ++__result; + for (--__n; __n > 0; --__n) + { + ++__first; + *__result = *__first; + ++__result; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +typename enable_if +< + __is_cpp17_random_access_iterator<_InputIterator>::value, + _OutputIterator +>::type +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return _VSTD::copy(__first, __first + difference_type(__n), __result); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_N_H diff --git a/include/__algorithm/count.h b/include/__algorithm/count.h new file mode 100644 index 000000000..81a2c186f --- /dev/null +++ b/include/__algorithm/count.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___ALGORITHM_COUNT_H +#define _LIBCPP___ALGORITHM_COUNT_H + +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (*__first == __value_) + ++__r; + return __r; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COUNT_H diff --git a/include/__algorithm/count_if.h b/include/__algorithm/count_if.h new file mode 100644 index 000000000..00f5d671d --- /dev/null +++ b/include/__algorithm/count_if.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___ALGORITHM_COUNT_IF_H +#define _LIBCPP___ALGORITHM_COUNT_IF_H + +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + typename iterator_traits<_InputIterator>::difference_type __r(0); + for (; __first != __last; ++__first) + if (__pred(*__first)) + ++__r; + return __r; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COUNT_IF_H diff --git a/include/__algorithm/equal.h b/include/__algorithm/equal.h new file mode 100644 index 000000000..4c9ad05ad --- /dev/null +++ b/include/__algorithm/equal.h @@ -0,0 +1,85 @@ +// -*- 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_EQUAL_H +#define _LIBCPP___ALGORITHM_EQUAL_H + +#include <__algorithm/comp.h> +#include <__config> +#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 + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return true; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + return false; + return __first1 == __last1 && __first2 == __last2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, + random_access_iterator_tag) { + if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) + return false; + return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, + _BinaryPredicate&>(__first1, __last1, __first2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred) { + return _VSTD::__equal<_BinaryPredicate&>( + __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), + typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_EQUAL_H diff --git a/include/__algorithm/equal_range.h b/include/__algorithm/equal_range.h new file mode 100644 index 000000000..e13f0bdd9 --- /dev/null +++ b/include/__algorithm/equal_range.h @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H +#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/half_positive.h> +#include <__algorithm/lower_bound.h> +#include <__algorithm/upper_bound.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> +__equal_range(_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 if (__comp(__value_, *__m)) + { + __last = __m; + __len = __l2; + } + else + { + _ForwardIterator __mp1 = __m; + return pair<_ForwardIterator, _ForwardIterator> + ( + _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp), + _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp) + ); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::equal_range(__first, __last, __value_, + __less::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H diff --git a/include/__algorithm/fill.h b/include/__algorithm/fill.h new file mode 100644 index 000000000..0cb36b02c --- /dev/null +++ b/include/__algorithm/fill.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___ALGORITHM_FILL_H +#define _LIBCPP___ALGORITHM_FILL_H + +#include <__algorithm/fill_n.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) +{ + for (; __first != __last; ++__first) + *__first = __value_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) +{ + _VSTD::fill_n(__first, __last - __first, __value_); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FILL_H diff --git a/include/__algorithm/fill_n.h b/include/__algorithm/fill_n.h new file mode 100644 index 000000000..857ac1415 --- /dev/null +++ b/include/__algorithm/fill_n.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___ALGORITHM_FILL_N_H +#define _LIBCPP___ALGORITHM_FILL_N_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +{ + for (; __n > 0; ++__first, (void) --__n) + *__first = __value_; + return __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +{ + return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FILL_N_H diff --git a/include/__algorithm/find.h b/include/__algorithm/find.h new file mode 100644 index 000000000..2a6dfbe41 --- /dev/null +++ b/include/__algorithm/find.h @@ -0,0 +1,32 @@ +// -*- 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_FIND_H +#define _LIBCPP___ALGORITHM_FIND_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator +find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { + for (; __first != __last; ++__first) + if (*__first == __value_) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_H diff --git a/include/__algorithm/find_end.h b/include/__algorithm/find_end.h new file mode 100644 index 000000000..dd0f7d7ac --- /dev/null +++ b/include/__algorithm/find_end.h @@ -0,0 +1,150 @@ +// -*- 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_FIND_END_OF_H +#define _LIBCPP___ALGORITHM_FIND_END_OF_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred, forward_iterator_tag, + forward_iterator_tag) { + // modeled after search algorithm + _ForwardIterator1 __r = __last1; // __last1 is the "default" answer + if (__first2 == __last2) + return __r; + while (true) { + while (true) { + if (__first1 == __last1) // if source exhausted return last correct answer + return __r; // (or __last1 if never found) + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _ForwardIterator1 __m1 = __first1; + _ForwardIterator2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one + __r = __first1; + ++__first1; + break; + } + if (++__m1 == __last1) // Source exhausted, return last answer + return __r; + if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end( + _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) { + // modeled after search algorithm (in reverse) + if (__first2 == __last2) + return __last1; // Everything matches an empty sequence + _BidirectionalIterator1 __l1 = __last1; + _BidirectionalIterator2 __l2 = __last2; + --__l2; + while (true) { + // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks + while (true) { + if (__first1 == __l1) // return __last1 if no element matches *__first2 + return __last1; + if (__pred(*--__l1, *__l2)) + break; + } + // *__l1 matches *__l2, now match elements before here + _BidirectionalIterator1 __m1 = __l1; + _BidirectionalIterator2 __m2 = __l2; + while (true) { + if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) + return __m1; + if (__m1 == __first1) // Otherwise if source exhaused, pattern not found + return __last1; + if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 + { + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( + _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + _D2 __len2 = __last2 - __first2; + if (__len2 == 0) + return __last1; + _D1 __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + const _RandomAccessIterator1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here + _RandomAccessIterator1 __l1 = __last1; + _RandomAccessIterator2 __l2 = __last2; + --__l2; + while (true) { + while (true) { + if (__s == __l1) + return __last1; + if (__pred(*--__l1, *__l2)) + break; + } + _RandomAccessIterator1 __m1 = __l1; + _RandomAccessIterator2 __m2 = __l2; + while (true) { + if (__m2 == __first2) + return __m1; + // no need to check range on __m1 because __s guarantees we have enough source + if (!__pred(*--__m1, *--__m2)) { + break; + } + } + } +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return _VSTD::__find_end<_BinaryPredicate&>( + __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H diff --git a/include/__algorithm/find_first_of.h b/include/__algorithm/find_first_of.h new file mode 100644 index 000000000..69354f617 --- /dev/null +++ b/include/__algorithm/find_first_of.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___ALGORITHM_FIND_FIRST_OF_H +#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + for (; __first1 != __last1; ++__first1) + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__first1, *__j)) + return __first1; + return __last1; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H diff --git a/include/__algorithm/find_if.h b/include/__algorithm/find_if.h new file mode 100644 index 000000000..a94196a16 --- /dev/null +++ b/include/__algorithm/find_if.h @@ -0,0 +1,32 @@ +// -*- 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_FIND_IF_H +#define _LIBCPP___ALGORITHM_FIND_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator +find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_IF_H diff --git a/include/__algorithm/find_if_not.h b/include/__algorithm/find_if_not.h new file mode 100644 index 000000000..e057db5ef --- /dev/null +++ b/include/__algorithm/find_if_not.h @@ -0,0 +1,32 @@ +// -*- 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_FIND_IF_NOT_H +#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator +find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H diff --git a/include/__algorithm/for_each.h b/include/__algorithm/for_each.h new file mode 100644 index 000000000..1612ffa5c --- /dev/null +++ b/include/__algorithm/for_each.h @@ -0,0 +1,32 @@ +// -*- 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_FOR_EACH_H +#define _LIBCPP___ALGORITHM_FOR_EACH_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_each(_InputIterator __first, + _InputIterator __last, + _Function __f) { + for (; __first != __last; ++__first) + __f(*__first); + return __f; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FOR_EACH_H diff --git a/include/__algorithm/for_each_n.h b/include/__algorithm/for_each_n.h new file mode 100644 index 000000000..00e3fb9c1 --- /dev/null +++ b/include/__algorithm/for_each_n.h @@ -0,0 +1,42 @@ +// -*- 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_FOR_EACH_N_H +#define _LIBCPP___ALGORITHM_FOR_EACH_N_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator for_each_n(_InputIterator __first, + _Size __orig_n, + _Function __f) { + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + while (__n > 0) { + __f(*__first); + ++__first; + --__n; + } + return __first; +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H diff --git a/include/__algorithm/generate.h b/include/__algorithm/generate.h new file mode 100644 index 000000000..10834cdb7 --- /dev/null +++ b/include/__algorithm/generate.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___ALGORITHM_GENERATE_H +#define _LIBCPP___ALGORITHM_GENERATE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) +{ + for (; __first != __last; ++__first) + *__first = __gen(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_GENERATE_H diff --git a/include/__algorithm/generate_n.h b/include/__algorithm/generate_n.h new file mode 100644 index 000000000..595007cdd --- /dev/null +++ b/include/__algorithm/generate_n.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___ALGORITHM_GENERATE_N_H +#define _LIBCPP___ALGORITHM_GENERATE_N_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) +{ + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + for (; __n > 0; ++__first, (void) --__n) + *__first = __gen(); + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_GENERATE_N_H diff --git a/include/__algorithm/half_positive.h b/include/__algorithm/half_positive.h new file mode 100644 index 000000000..5d36ff5da --- /dev/null +++ b/include/__algorithm/half_positive.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___ALGORITHM_HALF_POSITIVE_H +#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Perform division by two quickly for positive integers (llvm.org/PR39129) + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + is_integral<_Integral>::value, + _Integral +>::type +__half_positive(_Integral __value) +{ + return static_cast<_Integral>(static_cast::type>(__value) / 2); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + !is_integral<_Tp>::value, + _Tp +>::type +__half_positive(_Tp __value) +{ + return __value / 2; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H diff --git a/include/__algorithm/in_in_out_result.h b/include/__algorithm/in_in_out_result.h new file mode 100644 index 000000000..8d29b7b69 --- /dev/null +++ b/include/__algorithm/in_in_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_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_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 !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +template +struct in_in_out_result { + [[no_unique_address]] _I1 in1; + [[no_unique_address]] _I2 in2; + [[no_unique_address]] _O1 out; + + template + requires convertible_to && convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_II1, _II2, _OO1>() const& { + return {in1, in2, out}; + } + + template + requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2> && convertible_to<_O1, _OO1> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_II1, _II2, _OO1>() && { + return {_VSTD::move(in1), _VSTD::move(in2), _VSTD::move(out)}; + } +}; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H diff --git a/include/__algorithm/in_in_result.h b/include/__algorithm/in_in_result.h new file mode 100644 index 000000000..c8fe43d03 --- /dev/null +++ b/include/__algorithm/in_in_result.h @@ -0,0 +1,51 @@ +// -*- 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_IN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_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 !defined(_LIBCPP_HAS_NO_CONCEPTS) + +namespace ranges { + +template +struct in_in_result { + [[no_unique_address]] _I1 in1; + [[no_unique_address]] _I2 in2; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() const & { + return {in1, in2}; + } + + template + requires convertible_to<_I1, _II1> && convertible_to<_I2, _II2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_II1, _II2>() && { return {_VSTD::move(in1), _VSTD::move(in2)}; } +}; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git a/include/__algorithm/in_out_result.h b/include/__algorithm/in_out_result.h new file mode 100644 index 000000000..dcf72d08d --- /dev/null +++ b/include/__algorithm/in_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_RESULT_H +#define _LIBCPP___ALGORITHM_IN_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 !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +template +struct in_out_result { + [[no_unique_address]] _InputIterator in; + [[no_unique_address]] _OutputIterator out; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() const & { + return {in, out}; + } + + template + requires convertible_to<_InputIterator, _InputIterator2> && convertible_to<_OutputIterator, _OutputIterator2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InputIterator2, _OutputIterator2>() && { + return {_VSTD::move(in), _VSTD::move(out)}; + } +}; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git a/include/__algorithm/includes.h b/include/__algorithm/includes.h new file mode 100644 index 000000000..9d0bc694c --- /dev/null +++ b/include/__algorithm/includes.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_INCLUDES_H +#define _LIBCPP___ALGORITHM_INCLUDES_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) +{ + for (; __first2 != __last2; ++__first1) + { + if (__first1 == __last1 || __comp(*__first2, *__first1)) + return false; + if (!__comp(*__first1, *__first2)) + ++__first2; + } + return true; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) +{ + return _VSTD::includes(__first1, __last1, __first2, __last2, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_INCLUDES_H diff --git a/include/__algorithm/inplace_merge.h b/include/__algorithm/inplace_merge.h new file mode 100644 index 000000000..e6f1efc01 --- /dev/null +++ b/include/__algorithm/inplace_merge.h @@ -0,0 +1,231 @@ +//===----------------------------------------------------------------------===// +// +// 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_INPLACE_MERGE_H +#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/lower_bound.h> +#include <__algorithm/min.h> +#include <__algorithm/move.h> +#include <__algorithm/rotate.h> +#include <__algorithm/upper_bound.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __invert // invert the sense of a comparison +{ +private: + _Predicate __p_; +public: + _LIBCPP_INLINE_VISIBILITY __invert() {} + + _LIBCPP_INLINE_VISIBILITY + explicit __invert(_Predicate __p) : __p_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x) {return !__p_(__x);} + + template + _LIBCPP_INLINE_VISIBILITY + bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} +}; + +template +void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + _VSTD::move(__first1, __last1, __result); + return; + } + + if (__comp(*__first2, *__first1)) + { + *__result = _VSTD::move(*__first2); + ++__first2; + } + else + { + *__result = _VSTD::move(*__first1); + ++__first1; + } + } + // __first2 through __last2 are already in the right spot. +} + +template +void +__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + if (__len1 <= __len2) + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr(), (void) ++__i, (void) ++__p) + ::new ((void*)__p) value_type(_VSTD::move(*__i)); + _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp); + } + else + { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr(), (void) ++__i, (void) ++__p) + ::new ((void*)__p) value_type(_VSTD::move(*__i)); + typedef reverse_iterator<_BidirectionalIterator> _RBi; + typedef reverse_iterator _Rv; + typedef __invert<_Compare> _Inverted; + _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff), + _RBi(__middle), _RBi(__first), + _RBi(__last), _Inverted(__comp)); + } +} + +template +void +__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) +{ + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + while (true) + { + // if __middle == __last, we're done + if (__len2 == 0) + return; + if (__len1 <= __buff_size || __len2 <= __buff_size) + return _VSTD::__buffered_inplace_merge<_Compare> + (__first, __middle, __last, __comp, __len1, __len2, __buff); + // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 + for (; true; ++__first, (void) --__len1) + { + if (__len1 == 0) + return; + if (__comp(*__middle, *__first)) + break; + } + // __first < __middle < __last + // *__first > *__middle + // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that + // all elements in: + // [__first, __m1) <= [__middle, __m2) + // [__middle, __m2) < [__m1, __middle) + // [__m1, __middle) <= [__m2, __last) + // and __m1 or __m2 is in the middle of its range + _BidirectionalIterator __m1; // "median" of [__first, __middle) + _BidirectionalIterator __m2; // "median" of [__middle, __last) + difference_type __len11; // distance(__first, __m1) + difference_type __len21; // distance(__middle, __m2) + // binary search smaller range + if (__len1 < __len2) + { // __len >= 1, __len2 >= 2 + __len21 = __len2 / 2; + __m2 = __middle; + _VSTD::advance(__m2, __len21); + __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp); + __len11 = _VSTD::distance(__first, __m1); + } + else + { + if (__len1 == 1) + { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 + // It is known *__first > *__middle + swap(*__first, *__middle); + return; + } + // __len1 >= 2, __len2 >= 1 + __len11 = __len1 / 2; + __m1 = __first; + _VSTD::advance(__m1, __len11); + __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp); + __len21 = _VSTD::distance(__middle, __m2); + } + difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) + difference_type __len22 = __len2 - __len21; // distance(__m2, __last) + // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) + // swap middle two partitions + __middle = _VSTD::rotate(__m1, __middle, __m2); + // __len12 and __len21 now have swapped meanings + // merge smaller range with recursive call and larger with tail recursion elimination + if (__len11 + __len21 < __len12 + __len22) + { + _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); +// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + __first = __middle; + __middle = __m2; + __len1 = __len12; + __len2 = __len22; + } + else + { + _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); +// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + __last = __middle; + __middle = __m1; + __len1 = __len11; + __len2 = __len21; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare __comp) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + difference_type __len1 = _VSTD::distance(__first, __middle); + difference_type __len2 = _VSTD::distance(__middle, __last); + difference_type __buf_size = _VSTD::min(__len1, __len2); + pair __buf = _VSTD::get_temporary_buffer(__buf_size); + unique_ptr __h(__buf.first); + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, + __buf.first, __buf.second); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) +{ + _VSTD::inplace_merge(__first, __middle, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H diff --git a/include/__algorithm/is_heap.h b/include/__algorithm/is_heap.h new file mode 100644 index 000000000..925ba8bfb --- /dev/null +++ b/include/__algorithm/is_heap.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___ALGORITHM_IS_HEAP_H +#define _LIBCPP___ALGORITHM_IS_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/is_heap_until.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp) == __last; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::is_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_HEAP_H diff --git a/include/__algorithm/is_heap_until.h b/include/__algorithm/is_heap_until.h new file mode 100644 index 000000000..aa23b6d03 --- /dev/null +++ b/include/__algorithm/is_heap_until.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_IS_HEAP_UNTIL_H +#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + difference_type __p = 0; + difference_type __c = 1; + _RandomAccessIterator __pp = __first; + while (__c < __len) + { + _RandomAccessIterator __cp = __first + __c; + if (__comp(*__pp, *__cp)) + return __cp; + ++__c; + ++__cp; + if (__c == __len) + return __last; + if (__comp(*__pp, *__cp)) + return __cp; + ++__p; + ++__pp; + __c = 2 * __p + 1; + } + return __last; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + return _VSTD::__is_heap_until(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H diff --git a/include/__algorithm/is_partitioned.h b/include/__algorithm/is_partitioned.h new file mode 100644 index 000000000..e5b2214aa --- /dev/null +++ b/include/__algorithm/is_partitioned.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___ALGORITHM_IS_PARTITIONED_H +#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) +{ + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + if ( __first == __last ) + return true; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H diff --git a/include/__algorithm/is_permutation.h b/include/__algorithm/is_permutation.h new file mode 100644 index 000000000..344aa763a --- /dev/null +++ b/include/__algorithm/is_permutation.h @@ -0,0 +1,162 @@ +// -*- 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_IS_PERMUTATION_H +#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _BinaryPredicate __pred) { + // shorten sequences as much as possible by lopping of any equal prefix + for (; __first1 != __last1; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + if (__first1 == __last1) + return true; + + // __first1 != __last1 && *__first1 != *__first2 + typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; + _D1 __l1 = _VSTD::distance(__first1, __last1); + if (__l1 == _D1(1)) + return false; + _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); + // For each element in [f1, l1) see if there are the same number of + // equal elements in [f2, l2) + for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { + // Have we already counted the number of *__i in [f1, l1)? + _ForwardIterator1 __match = __first1; + for (; __match != __i; ++__match) + if (__pred(*__match, *__i)) + break; + if (__match == __i) { + // Count number of *__i in [f2, l2) + _D1 __c2 = 0; + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__i, *__j)) + ++__c2; + if (__c2 == 0) + return false; + // Count number of *__i in [__i, l1) (we can start with 1) + _D1 __c1 = 1; + for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) + if (__pred(*__i, *__j)) + ++__c1; + if (__c1 != __c2) + return false; + } + } + return true; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { + // shorten sequences as much as possible by lopping of any equal prefix + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + if (__first1 == __last1) + return __first2 == __last2; + else if (__first2 == __last2) + return false; + + typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; + _D1 __l1 = _VSTD::distance(__first1, __last1); + + typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; + _D2 __l2 = _VSTD::distance(__first2, __last2); + if (__l1 != __l2) + return false; + + // For each element in [f1, l1) see if there are the same number of + // equal elements in [f2, l2) + for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { + // Have we already counted the number of *__i in [f1, l1)? + _ForwardIterator1 __match = __first1; + for (; __match != __i; ++__match) + if (__pred(*__match, *__i)) + break; + if (__match == __i) { + // Count number of *__i in [f2, l2) + _D1 __c2 = 0; + for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) + if (__pred(*__i, *__j)) + ++__c2; + if (__c2 == 0) + return false; + // Count number of *__i in [__i, l1) (we can start with 1) + _D1 __c1 = 1; + for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) + if (__pred(*__i, *__j)) + ++__c1; + if (__c1 != __c2) + return false; + } + } + return true; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, + _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, + _BinaryPredicate __pred, random_access_iterator_tag, + random_access_iterator_tag) { + if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) + return false; + return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, + _BinaryPredicate&>(__first1, __last1, __first2, __pred); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + return _VSTD::__is_permutation<_BinaryPredicate&>( + __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H diff --git a/include/__algorithm/is_sorted.h b/include/__algorithm/is_sorted.h new file mode 100644 index 000000000..57953295a --- /dev/null +++ b/include/__algorithm/is_sorted.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___ALGORITHM_IS_SORTED_H +#define _LIBCPP___ALGORITHM_IS_SORTED_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/is_sorted_until.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp) == __last; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_SORTED_H diff --git a/include/__algorithm/is_sorted_until.h b/include/__algorithm/is_sorted_until.h new file mode 100644 index 000000000..57cad4776 --- /dev/null +++ b/include/__algorithm/is_sorted_until.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___ALGORITHM_IS_SORTED_UNTIL_H +#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__comp(*__i, *__first)) + return __i; + __first = __i; + } + } + return __last; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::is_sorted_until(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H diff --git a/include/__algorithm/iter_swap.h b/include/__algorithm/iter_swap.h new file mode 100644 index 000000000..9f7d0d776 --- /dev/null +++ b/include/__algorithm/iter_swap.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___ALGORITHM_ITER_SWAP_H +#define _LIBCPP___ALGORITHM_ITER_SWAP_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void iter_swap(_ForwardIterator1 __a, + _ForwardIterator2 __b) + // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) + _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) { + swap(*__a, *__b); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H diff --git a/include/__algorithm/lexicographical_compare.h b/include/__algorithm/lexicographical_compare.h new file mode 100644 index 000000000..55a1da620 --- /dev/null +++ b/include/__algorithm/lexicographical_compare.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_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ + for (; __first2 != __last2; ++__first1, (void) ++__first2) + { + if (__first1 == __last1 || __comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return false; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) +{ + return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H diff --git a/include/__algorithm/lower_bound.h b/include/__algorithm/lower_bound.h new file mode 100644 index 000000000..663a0b162 --- /dev/null +++ b/include/__algorithm/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_LOWER_BOUND_H +#define _LIBCPP___ALGORITHM_LOWER_BOUND_H + +#include <__algorithm/comp.h> +#include <__algorithm/half_positive.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_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; + } + return __first; +} + +template +_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); +} + +template +_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::value_type, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H diff --git a/include/__algorithm/make_heap.h b/include/__algorithm/make_heap.h new file mode 100644 index 000000000..f489addaf --- /dev/null +++ b/include/__algorithm/make_heap.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_MAKE_HEAP_H +#define _LIBCPP___ALGORITHM_MAKE_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/sift_down.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __n = __last - __first; + if (__n > 1) + { + // start from the first parent, there is no need to consider children + for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) + { + _VSTD::__sift_down<_Compare>(__first, __comp, __n, __first + __start); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::make_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H diff --git a/include/__algorithm/max.h b/include/__algorithm/max.h new file mode 100644 index 000000000..0bbc971e0 --- /dev/null +++ b/include/__algorithm/max.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_MAX_H +#define _LIBCPP___ALGORITHM_MAX_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/max_element.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +max(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__a, __b) ? __b : __a; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +max(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::max(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +max(initializer_list<_Tp> __t, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return *_VSTD::__max_element<_Comp_ref>(__t.begin(), __t.end(), __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +max(initializer_list<_Tp> __t) +{ + return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MAX_H diff --git a/include/__algorithm/max_element.h b/include/__algorithm/max_element.h new file mode 100644 index 000000000..db2937260 --- /dev/null +++ b/include/__algorithm/max_element.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___ALGORITHM_MAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::max_element requires a ForwardIterator"); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__first, *__i)) + __first = __i; + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__max_element<_Comp_ref>(__first, __last, __comp); +} + + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::max_element(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H diff --git a/include/__algorithm/merge.h b/include/__algorithm/merge.h new file mode 100644 index 000000000..918264937 --- /dev/null +++ b/include/__algorithm/merge.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_MERGE_H +#define _LIBCPP___ALGORITHM_MERGE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +__merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MERGE_H diff --git a/include/__algorithm/min.h b/include/__algorithm/min.h new file mode 100644 index 000000000..ed2d3b878 --- /dev/null +++ b/include/__algorithm/min.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_MIN_H +#define _LIBCPP___ALGORITHM_MIN_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/min_element.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +min(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? __b : __a; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +const _Tp& +min(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::min(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +min(initializer_list<_Tp> __t, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return *_VSTD::__min_element<_Comp_ref>(__t.begin(), __t.end(), __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp +min(initializer_list<_Tp> __t) +{ + return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MIN_H diff --git a/include/__algorithm/min_element.h b/include/__algorithm/min_element.h new file mode 100644 index 000000000..407c7f933 --- /dev/null +++ b/include/__algorithm/min_element.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___ALGORITHM_MIN_ELEMENT_H +#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::min_element requires a ForwardIterator"); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__i, *__first)) + __first = __i; + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__min_element<_Comp_ref>(__first, __last, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last) +{ + return _VSTD::min_element(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H diff --git a/include/__algorithm/minmax.h b/include/__algorithm/minmax.h new file mode 100644 index 000000000..0bf88a70b --- /dev/null +++ b/include/__algorithm/minmax.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// 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_MINMAX_H +#define _LIBCPP___ALGORITHM_MINMAX_H + +#include <__algorithm/comp.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair +minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) +{ + return __comp(__b, __a) ? pair(__b, __a) : + pair(__a, __b); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair +minmax(const _Tp& __a, const _Tp& __b) +{ + return _VSTD::minmax(__a, __b, __less<_Tp>()); +} + +#ifndef _LIBCPP_CXX03_LANG + +template +_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; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t) +{ + return _VSTD::minmax(__t, __less<_Tp>()); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MINMAX_H diff --git a/include/__algorithm/minmax_element.h b/include/__algorithm/minmax_element.h new file mode 100644 index 000000000..5d7686038 --- /dev/null +++ b/include/__algorithm/minmax_element.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_MINMAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_ForwardIterator, _ForwardIterator> +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; +} + +template +_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::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H diff --git a/include/__algorithm/mismatch.h b/include/__algorithm/mismatch.h new file mode 100644 index 000000000..230ade03d --- /dev/null +++ b/include/__algorithm/mismatch.h @@ -0,0 +1,67 @@ +// -*- 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_MISMATCH_H +#define _LIBCPP___ALGORITHM_MISMATCH_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 11 +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __pred) { + for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) + if (!__pred(*__first1, *__first2)) + break; + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + typedef typename iterator_traits<_InputIterator1>::value_type __v1; + typedef typename iterator_traits<_InputIterator2>::value_type __v2; + return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MISMATCH_H diff --git a/include/__algorithm/move.h b/include/__algorithm/move.h new file mode 100644 index 000000000..fa118f471 --- /dev/null +++ b/include/__algorithm/move.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_MOVE_H +#define _LIBCPP___ALGORITHM_MOVE_H + +#include <__algorithm/unwrap_iter.h> +#include <__config> +#include <__utility/move.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// move + +template +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; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_OutputIterator +__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return _VSTD::__move_constexpr(__first, __last, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_move_assignable<_Up>::value, + _Up* +>::type +__move(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + return __result + __n; +} + +template +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))); + } +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MOVE_H diff --git a/include/__algorithm/move_backward.h b/include/__algorithm/move_backward.h new file mode 100644 index 000000000..a4e3828b6 --- /dev/null +++ b/include/__algorithm/move_backward.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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_MOVE_BACKWARD_H +#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H + +#include <__algorithm/unwrap_iter.h> +#include <__config> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_OutputIterator +__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + while (__first != __last) + *--__result = _VSTD::move(*--__last); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_OutputIterator +__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return _VSTD::__move_backward_constexpr(__first, __last, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +typename enable_if +< + is_same::type, _Up>::value && + is_trivially_move_assignable<_Up>::value, + _Up* +>::type +__move_backward(_Tp* __first, _Tp* __last, _Up* __result) +{ + const size_t __n = static_cast(__last - __first); + if (__n > 0) + { + __result -= __n; + _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_BidirectionalIterator2 +move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) +{ + if (__libcpp_is_constant_evaluated()) { + return _VSTD::__move_backward_constexpr(__first, __last, __result); + } else { + return _VSTD::__rewrap_iter(__result, + _VSTD::__move_backward(_VSTD::__unwrap_iter(__first), + _VSTD::__unwrap_iter(__last), + _VSTD::__unwrap_iter(__result))); + } +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H diff --git a/include/__algorithm/next_permutation.h b/include/__algorithm/next_permutation.h new file mode 100644 index 000000000..eb81cceb7 --- /dev/null +++ b/include/__algorithm/next_permutation.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_NEXT_PERMUTATION_H +#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/reverse.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + _BidirectionalIterator __i = __last; + if (__first == __last || __first == --__i) + return false; + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*--__i, *__ip1)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + ; + swap(*__i, *__j); + _VSTD::reverse(__ip1, __last); + return true; + } + if (__i == __first) + { + _VSTD::reverse(__first, __last); + return false; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::next_permutation(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H diff --git a/include/__algorithm/none_of.h b/include/__algorithm/none_of.h new file mode 100644 index 000000000..10339e241 --- /dev/null +++ b/include/__algorithm/none_of.h @@ -0,0 +1,32 @@ +// -*- 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_NONE_OF_H +#define _LIBCPP___ALGORITHM_NONE_OF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NONE_OF_H diff --git a/include/__algorithm/nth_element.h b/include/__algorithm/nth_element.h new file mode 100644 index 000000000..3afbd6c61 --- /dev/null +++ b/include/__algorithm/nth_element.h @@ -0,0 +1,248 @@ +//===----------------------------------------------------------------------===// +// +// 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_NTH_ELEMENT_H +#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) +# include <__algorithm/shuffle.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 bool +__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, + _RandomAccessIterator __m, _Compare __comp) +{ + // manually guard downward moving __j against __i + while (true) { + if (__i == --__j) { + return false; + } + if (__comp(*__j, *__m)) { + return true; // found guard for downward moving __j, now use unguarded partition + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 void +__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) +{ + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + const difference_type __limit = 7; + while (true) + { + if (__nth == __last) + return; + difference_type __len = __last - __first; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return; + case 3: + { + _RandomAccessIterator __m = __first; + _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); + return; + } + } + if (__len <= __limit) + { + _VSTD::__selection_sort<_Compare>(__first, __last, __comp); + return; + } + // __len > __limit >= 3 + _RandomAccessIterator __m = __first + __len/2; + _RandomAccessIterator __lm1 = __last; + unsigned __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, *__lm1 is known to be <= *__m + // 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 + if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { + swap(*__i, *__j); + ++__n_swaps; + } else { + // *__first == *__m, *__m <= all other elements + // Partition 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 + } else 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, + if (__nth < __i) { + return; + } + // __nth_element the second part + // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp); + __first = __i; + continue; + } + } + ++__i; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // if not yet partitioned... + if (__i < __j) + { + // known that *(__i - 1) < *__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 (__nth == __i) + return; + if (__n_swaps == 0) + { + // We were given a perfectly partitioned sequence. Coincidence? + if (__nth < __i) + { + // Check for [__first, __i) already sorted + __j = __m = __first; + while (true) { + if (++__j == __i) { + // [__first, __i) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } + else + { + // Check for [__i, __last) already sorted + __j = __m = __i; + while (true) { + if (++__j == __last) { + // [__i, __last) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } + } + // __nth_element on range containing __nth + if (__nth < __i) + { + // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp); + __last = __i; + } + else + { + // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp); + __first = ++__i; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) +{ + _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last); + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp); + _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __nth); + if (__nth != __last) { + _LIBCPP_DEBUG_RANDOMIZE_RANGE(++__nth, __last); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) +{ + _VSTD::nth_element(__first, __nth, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H diff --git a/include/__algorithm/partial_sort.h b/include/__algorithm/partial_sort.h new file mode 100644 index 000000000..a92a7e566 --- /dev/null +++ b/include/__algorithm/partial_sort.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_PARTIAL_SORT_H +#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/sift_down.h> +#include <__algorithm/sort_heap.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) +# include <__algorithm/shuffle.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void +__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _Compare __comp) +{ + if (__first == __middle) + return; + _VSTD::__make_heap<_Compare>(__first, __middle, __comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; + for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) + { + if (__comp(*__i, *__first)) + { + swap(*__i, *__first); + _VSTD::__sift_down<_Compare>(__first, __comp, __len, __first); + } + } + _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + _Compare __comp) +{ + _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last); + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp); + _LIBCPP_DEBUG_RANDOMIZE_RANGE(__middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + _VSTD::partial_sort(__first, __middle, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H diff --git a/include/__algorithm/partial_sort_copy.h b/include/__algorithm/partial_sort_copy.h new file mode 100644 index 000000000..67a62bae1 --- /dev/null +++ b/include/__algorithm/partial_sort_copy.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_PARTIAL_SORT_COPY_H +#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/sift_down.h> +#include <__algorithm/sort_heap.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator +__partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +{ + _RandomAccessIterator __r = __result_first; + if (__r != __result_last) + { + for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) + *__r = *__first; + _VSTD::__make_heap<_Compare>(__result_first, __r, __comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; + for (; __first != __last; ++__first) + if (__comp(*__first, *__result_first)) + { + *__result_first = *__first; + _VSTD::__sift_down<_Compare>(__result_first, __comp, __len, __result_first); + } + _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_RandomAccessIterator +partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) +{ + return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H diff --git a/include/__algorithm/partition.h b/include/__algorithm/partition.h new file mode 100644 index 000000000..131c5d373 --- /dev/null +++ b/include/__algorithm/partition.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_PARTITION_H +#define _LIBCPP___ALGORITHM_PARTITION_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) +{ + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + for (_ForwardIterator __p = __first; ++__p != __last;) + { + if (__pred(*__p)) + { + swap(*__first, *__p); + ++__first; + } + } + return __first; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator +__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + bidirectional_iterator_tag) +{ + while (true) + { + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + do + { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + swap(*__first, *__last); + ++__first; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator +partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + return _VSTD::__partition<_Predicate&>( + __first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_H diff --git a/include/__algorithm/partition_copy.h b/include/__algorithm/partition_copy.h new file mode 100644 index 000000000..d34944589 --- /dev/null +++ b/include/__algorithm/partition_copy.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___ALGORITHM_PARTITION_COPY_H +#define _LIBCPP___ALGORITHM_PARTITION_COPY_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include // pair + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> +partition_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator1 __out_true, _OutputIterator2 __out_false, + _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (__pred(*__first)) + { + *__out_true = *__first; + ++__out_true; + } + else + { + *__out_false = *__first; + ++__out_false; + } + } + return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H diff --git a/include/__algorithm/partition_point.h b/include/__algorithm/partition_point.h new file mode 100644 index 000000000..18e6e6f68 --- /dev/null +++ b/include/__algorithm/partition_point.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H +#define _LIBCPP___ALGORITHM_PARTITION_POINT_H + +#include <__algorithm/half_positive.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + 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 (__pred(*__m)) + { + __first = ++__m; + __len -= __l2 + 1; + } + else + __len = __l2; + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H diff --git a/include/__algorithm/pop_heap.h b/include/__algorithm/pop_heap.h new file mode 100644 index 000000000..c1cc8016a --- /dev/null +++ b/include/__algorithm/pop_heap.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___ALGORITHM_POP_HEAP_H +#define _LIBCPP___ALGORITHM_POP_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/sift_down.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + if (__len > 1) + { + swap(*__first, *--__last); + _VSTD::__sift_down<_Compare>(__first, __comp, __len - 1, __first); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::pop_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_POP_HEAP_H diff --git a/include/__algorithm/prev_permutation.h b/include/__algorithm/prev_permutation.h new file mode 100644 index 000000000..457c2695b --- /dev/null +++ b/include/__algorithm/prev_permutation.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_PREV_PERMUTATION_H +#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/reverse.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + _BidirectionalIterator __i = __last; + if (__first == __last || __first == --__i) + return false; + while (true) + { + _BidirectionalIterator __ip1 = __i; + if (__comp(*__ip1, *--__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + ; + swap(*__i, *__j); + _VSTD::reverse(__ip1, __last); + return true; + } + if (__i == __first) + { + _VSTD::reverse(__first, __last); + return false; + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + return _VSTD::prev_permutation(__first, __last, + __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H diff --git a/include/__algorithm/push_heap.h b/include/__algorithm/push_heap.h new file mode 100644 index 000000000..864d419fa --- /dev/null +++ b/include/__algorithm/push_heap.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___ALGORITHM_PUSH_HEAP_H +#define _LIBCPP___ALGORITHM_PUSH_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 void +__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (__len > 1) + { + __len = (__len - 2) / 2; + _RandomAccessIterator __ptr = __first + __len; + if (__comp(*__ptr, *--__last)) + { + value_type __t(_VSTD::move(*__last)); + do + { + *__last = _VSTD::move(*__ptr); + __last = __ptr; + if (__len == 0) + break; + __len = (__len - 1) / 2; + __ptr = __first + __len; + } while (__comp(*__ptr, __t)); + *__last = _VSTD::move(__t); + } + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::push_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H diff --git a/include/__algorithm/remove.h b/include/__algorithm/remove.h new file mode 100644 index 000000000..681b9cc76 --- /dev/null +++ b/include/__algorithm/remove.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___ALGORITHM_REMOVE_H +#define _LIBCPP___ALGORITHM_REMOVE_H + +#include <__algorithm/find.h> +#include <__algorithm/find_if.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + __first = _VSTD::find(__first, __last, __value_); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!(*__i == __value_)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_H diff --git a/include/__algorithm/remove_copy.h b/include/__algorithm/remove_copy.h new file mode 100644 index 000000000..338ca9430 --- /dev/null +++ b/include/__algorithm/remove_copy.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___ALGORITHM_REMOVE_COPY_H +#define _LIBCPP___ALGORITHM_REMOVE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) +{ + for (; __first != __last; ++__first) + { + if (!(*__first == __value_)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H diff --git a/include/__algorithm/remove_copy_if.h b/include/__algorithm/remove_copy_if.h new file mode 100644 index 000000000..a55638722 --- /dev/null +++ b/include/__algorithm/remove_copy_if.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___ALGORITHM_REMOVE_COPY_IF_H +#define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) +{ + for (; __first != __last; ++__first) + { + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + } + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H diff --git a/include/__algorithm/remove_if.h b/include/__algorithm/remove_if.h new file mode 100644 index 000000000..36f817cfa --- /dev/null +++ b/include/__algorithm/remove_if.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___ALGORITHM_REMOVE_IF_H +#define _LIBCPP___ALGORITHM_REMOVE_IF_H + +#include <__algorithm/find_if.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + __first = _VSTD::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); + if (__first != __last) + { + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (!__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + } + } + return __first; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REMOVE_IF_H diff --git a/include/__algorithm/replace.h b/include/__algorithm/replace.h new file mode 100644 index 000000000..2bc96ffc8 --- /dev/null +++ b/include/__algorithm/replace.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___ALGORITHM_REPLACE_H +#define _LIBCPP___ALGORITHM_REPLACE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_H diff --git a/include/__algorithm/replace_copy.h b/include/__algorithm/replace_copy.h new file mode 100644 index 000000000..c6c5fe32e --- /dev/null +++ b/include/__algorithm/replace_copy.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___ALGORITHM_REPLACE_COPY_H +#define _LIBCPP___ALGORITHM_REPLACE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H diff --git a/include/__algorithm/replace_copy_if.h b/include/__algorithm/replace_copy_if.h new file mode 100644 index 000000000..274d8e630 --- /dev/null +++ b/include/__algorithm/replace_copy_if.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___ALGORITHM_REPLACE_COPY_IF_H +#define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first, (void) ++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H diff --git a/include/__algorithm/replace_if.h b/include/__algorithm/replace_if.h new file mode 100644 index 000000000..bcc3feb2f --- /dev/null +++ b/include/__algorithm/replace_if.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___ALGORITHM_REPLACE_IF_H +#define _LIBCPP___ALGORITHM_REPLACE_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) +{ + for (; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REPLACE_IF_H diff --git a/include/__algorithm/reverse.h b/include/__algorithm/reverse.h new file mode 100644 index 000000000..1198aeaf4 --- /dev/null +++ b/include/__algorithm/reverse.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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_REVERSE_H +#define _LIBCPP___ALGORITHM_REVERSE_H + +#include <__algorithm/iter_swap.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) +{ + while (__first != __last) + { + if (__first == --__last) + break; + _VSTD::iter_swap(__first, __last); + ++__first; + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) +{ + if (__first != __last) + for (; __first < --__last; ++__first) + _VSTD::iter_swap(__first, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REVERSE_H diff --git a/include/__algorithm/reverse_copy.h b/include/__algorithm/reverse_copy.h new file mode 100644 index 000000000..002c0344a --- /dev/null +++ b/include/__algorithm/reverse_copy.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___ALGORITHM_REVERSE_COPY_H +#define _LIBCPP___ALGORITHM_REVERSE_COPY_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + for (; __first != __last; ++__result) + *__result = *--__last; + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H diff --git a/include/__algorithm/rotate.h b/include/__algorithm/rotate.h new file mode 100644 index 000000000..fd6d3e9c1 --- /dev/null +++ b/include/__algorithm/rotate.h @@ -0,0 +1,200 @@ +//===----------------------------------------------------------------------===// +// +// 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_ROTATE_H +#define _LIBCPP___ALGORITHM_ROTATE_H + +#include <__algorithm/move.h> +#include <__algorithm/move_backward.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +__rotate_left(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + value_type __tmp = _VSTD::move(*__first); + _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); + *__lm1 = _VSTD::move(__tmp); + return __lm1; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator +__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + _BidirectionalIterator __lm1 = _VSTD::prev(__last); + value_type __tmp = _VSTD::move(*__lm1); + _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); + *__first = _VSTD::move(__tmp); + return __fp1; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator +__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + _ForwardIterator __i = __middle; + while (true) + { + swap(*__first, *__i); + ++__first; + if (++__i == __last) + break; + if (__first == __middle) + __middle = __i; + } + _ForwardIterator __r = __first; + if (__first != __middle) + { + __i = __middle; + while (true) + { + swap(*__first, *__i); + ++__first; + if (++__i == __last) + { + if (__first == __middle) + break; + __i = __middle; + } + else if (__first == __middle) + __middle = __i; + } + } + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral +__algo_gcd(_Integral __x, _Integral __y) +{ + do + { + _Integral __t = __x % __y; + __x = __y; + __y = __t; + } while (__y); + return __x; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator +__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + + const difference_type __m1 = __middle - __first; + const difference_type __m2 = __last - __middle; + if (__m1 == __m2) + { + _VSTD::swap_ranges(__first, __middle, __middle); + return __middle; + } + const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); + for (_RandomAccessIterator __p = __first + __g; __p != __first;) + { + value_type __t(_VSTD::move(*--__p)); + _RandomAccessIterator __p1 = __p; + _RandomAccessIterator __p2 = __p1 + __m1; + do + { + *__p1 = _VSTD::move(*__p2); + __p1 = __p2; + const difference_type __d = __last - __p2; + if (__m1 < __d) + __p2 += __m1; + else + __p2 = __first + (__m1 - __d); + } while (__p2 != __p); + *__p1 = _VSTD::move(__t); + } + return __first + __m2; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, + _VSTD::forward_iterator_tag) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator +__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + bidirectional_iterator_tag) +{ + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + if (_VSTD::next(__middle) == __last) + return _VSTD::__rotate_right(__first, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator +__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, + random_access_iterator_tag) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (is_trivially_move_assignable::value) + { + if (_VSTD::next(__first) == __middle) + return _VSTD::__rotate_left(__first, __last); + if (_VSTD::next(__middle) == __last) + return _VSTD::__rotate_right(__first, __last); + return _VSTD::__rotate_gcd(__first, __middle, __last); + } + return _VSTD::__rotate_forward(__first, __middle, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) +{ + if (__first == __middle) + return __last; + if (__middle == __last) + return __first; + return _VSTD::__rotate(__first, __middle, __last, + typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ROTATE_H diff --git a/include/__algorithm/rotate_copy.h b/include/__algorithm/rotate_copy.h new file mode 100644 index 000000000..f9e644c88 --- /dev/null +++ b/include/__algorithm/rotate_copy.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___ALGORITHM_ROTATE_COPY_H +#define _LIBCPP___ALGORITHM_ROTATE_COPY_H + +#include <__algorithm/copy.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) +{ + return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H diff --git a/include/__algorithm/sample.h b/include/__algorithm/sample.h new file mode 100644 index 000000000..33264c4ea --- /dev/null +++ b/include/__algorithm/sample.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___ALGORITHM_SAMPLE_H +#define _LIBCPP___ALGORITHM_SAMPLE_H + +#include <__algorithm/min.h> +#include <__config> +#include <__debug> +#include <__random/uniform_int_distribution.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator & __g, + input_iterator_tag) { + + _Distance __k = 0; + for (; __first != __last && __k < __n; ++__first, (void) ++__k) + __output_iter[__k] = *__first; + _Distance __sz = __k; + for (; __first != __last; ++__first, (void) ++__k) { + _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); + if (__r < __sz) + __output_iter[__r] = *__first; + } + return __output_iter + _VSTD::min(__n, __k); +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + forward_iterator_tag) { + _Distance __unsampled_sz = _VSTD::distance(__first, __last); + for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { + _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); + if (__r < __n) { + *__output_iter++ = *__first; + --__n; + } + } + return __output_iter; +} + +template +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __output_iter, + _Distance __n, _UniformRandomNumberGenerator& __g) { + typedef typename iterator_traits<_PopulationIterator>::iterator_category + _PopCategory; + typedef typename iterator_traits<_PopulationIterator>::difference_type + _Difference; + static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || + __is_cpp17_random_access_iterator<_SampleIterator>::value, + "SampleIterator must meet the requirements of RandomAccessIterator"); + typedef typename common_type<_Distance, _Difference>::type _CommonType; + _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); + return _VSTD::__sample( + __first, __last, __output_iter, _CommonType(__n), + __g, _PopCategory()); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY +_SampleIterator sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __output_iter, + _Distance __n, _UniformRandomNumberGenerator&& __g) { + return _VSTD::__sample(__first, __last, __output_iter, __n, __g); +} +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SAMPLE_H diff --git a/include/__algorithm/search.h b/include/__algorithm/search.h new file mode 100644 index 000000000..cfaec0ed1 --- /dev/null +++ b/include/__algorithm/search.h @@ -0,0 +1,125 @@ +// -*- 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_SEARCH_H +#define _LIBCPP___ALGORITHM_SEARCH_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +pair<_ForwardIterator1, _ForwardIterator1> + _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { + if (__first2 == __last2) + return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence + while (true) { + // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks + while (true) { + if (__first1 == __last1) // return __last1 if no element matches *__first2 + return _VSTD::make_pair(__last1, __last1); + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _ForwardIterator1 __m1 = __first1; + _ForwardIterator2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) + return _VSTD::make_pair(__first1, __m1); + if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found + return _VSTD::make_pair(__last1, __last1); + if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1> +__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, + random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + const _D2 __len2 = __last2 - __first2; + if (__len2 == 0) + return _VSTD::make_pair(__first1, __first1); + const _D1 __len1 = __last1 - __first1; + if (__len1 < __len2) + return _VSTD::make_pair(__last1, __last1); + const _RandomAccessIterator1 __s = __last1 - _D1(__len2 - 1); // Start of pattern match can't go beyond here + + while (true) { + while (true) { + if (__first1 == __s) + return _VSTD::make_pair(__last1, __last1); + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + + _RandomAccessIterator1 __m1 = __first1; + _RandomAccessIterator2 __m2 = __first2; + while (true) { + if (++__m2 == __last2) + return _VSTD::make_pair(__first1, __first1 + _D1(__len2)); + ++__m1; // no need to check range on __m1 because __s guarantees we have enough source + if (!__pred(*__m1, *__m2)) { + ++__first1; + break; + } + } + } +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return _VSTD::__search<_BinaryPredicate&>( + __first1, __last1, __first2, __last2, __pred, + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()).first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; + return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +} + +#if _LIBCPP_STD_VER > 14 +template +_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { + return __s(__f, __l).first; +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SEARCH_H diff --git a/include/__algorithm/search_n.h b/include/__algorithm/search_n.h new file mode 100644 index 000000000..e4576cc76 --- /dev/null +++ b/include/__algorithm/search_n.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___ALGORITHM_SEARCH_N_H +#define _LIBCPP___ALGORITHM_SEARCH_N_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include // __convert_to_integral + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, + _Size __count, const _Tp& __value_, _BinaryPredicate __pred, + forward_iterator_tag) { + if (__count <= 0) + return __first; + while (true) { + // Find first element in sequence that matchs __value_, with a mininum of loop checks + while (true) { + if (__first == __last) // return __last if no element matches __value_ + return __last; + if (__pred(*__first, __value_)) + break; + ++__first; + } + // *__first matches __value_, now match elements after here + _ForwardIterator __m = __first; + _Size __c(0); + while (true) { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return __first; + if (++__m == __last) // Otherwise if source exhaused, pattern not found + return __last; + if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Size __count, + const _Tp& __value_, _BinaryPredicate __pred, + random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + if (__count <= 0) + return __first; + _Size __len = static_cast<_Size>(__last - __first); + if (__len < __count) + return __last; + const _RandomAccessIterator __s = __last - difference_type(__count - 1); // Start of pattern match can't go beyond here + while (true) { + // Find first element in sequence that matchs __value_, with a mininum of loop checks + while (true) { + if (__first >= __s) // return __last if no element matches __value_ + return __last; + if (__pred(*__first, __value_)) + break; + ++__first; + } + // *__first matches __value_, now match elements after here + _RandomAccessIterator __m = __first; + _Size __c(0); + while (true) { + if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) + return __first; + ++__m; // no need to check range on __m because __s guarantees we have enough source + if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + { + __first = __m; + ++__first; + break; + } // else there is a match, check next elements + } + } +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n( + _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) { + return _VSTD::__search_n<_BinaryPredicate&>( + __first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred, + typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) { + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value_, __equal_to<__v, _Tp>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SEARCH_N_H diff --git a/include/__algorithm/set_difference.h b/include/__algorithm/set_difference.h new file mode 100644 index 000000000..00f61e070 --- /dev/null +++ b/include/__algorithm/set_difference.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_SET_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + else + { + if (!__comp(*__first2, *__first1)) + ++__first1; + ++__first2; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H diff --git a/include/__algorithm/set_intersection.h b/include/__algorithm/set_intersection.h new file mode 100644 index 000000000..f6aa38217 --- /dev/null +++ b/include/__algorithm/set_intersection.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_SET_INTERSECTION_H +#define _LIBCPP___ALGORITHM_SET_INTERSECTION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + ++__first1; + else + { + if (!__comp(*__first2, *__first1)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + ++__first2; + } + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H diff --git a/include/__algorithm/set_symmetric_difference.h b/include/__algorithm/set_symmetric_difference.h new file mode 100644 index 000000000..5b5c2acff --- /dev/null +++ b/include/__algorithm/set_symmetric_difference.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_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + while (__first1 != __last1) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__result; + ++__first1; + } + else + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__result; + } + else + ++__first1; + ++__first2; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H diff --git a/include/__algorithm/set_union.h b/include/__algorithm/set_union.h new file mode 100644 index 000000000..5b3e3af79 --- /dev/null +++ b/include/__algorithm/set_union.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_SET_UNION_H +#define _LIBCPP___ALGORITHM_SET_UNION_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/copy.h> +#include <__config> +#include <__iterator/iterator_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + return _VSTD::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + if (!__comp(*__first1, *__first2)) + ++__first2; + *__result = *__first1; + ++__first1; + } + } + return _VSTD::copy(__first2, __last2, __result); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) +{ + return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SET_UNION_H diff --git a/include/__algorithm/shift_left.h b/include/__algorithm/shift_left.h new file mode 100644 index 000000000..0466a3188 --- /dev/null +++ b/include/__algorithm/shift_left.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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_SHIFT_LEFT_H +#define _LIBCPP___ALGORITHM_SHIFT_LEFT_H + +#include <__algorithm/move.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_ForwardIterator +shift_left(_ForwardIterator __first, _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) +{ + if (__n == 0) { + return __last; + } + + _ForwardIterator __m = __first; + if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { + if (__n >= __last - __first) { + return __first; + } + __m += __n; + } else { + for (; __n > 0; --__n) { + if (__m == __last) { + return __first; + } + ++__m; + } + } + return _VSTD::move(__m, __last, __first); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H diff --git a/include/__algorithm/shift_right.h b/include/__algorithm/shift_right.h new file mode 100644 index 000000000..121712e85 --- /dev/null +++ b/include/__algorithm/shift_right.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___ALGORITHM_SHIFT_RIGHT_H +#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H + +#include <__algorithm/move.h> +#include <__algorithm/move_backward.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_ForwardIterator +shift_right(_ForwardIterator __first, _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) +{ + if (__n == 0) { + return __first; + } + + if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { + decltype(__n) __d = __last - __first; + if (__n >= __d) { + return __last; + } + _ForwardIterator __m = __first + (__d - __n); + return _VSTD::move_backward(__first, __m, __last); + } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) { + _ForwardIterator __m = __last; + for (; __n > 0; --__n) { + if (__m == __first) { + return __last; + } + --__m; + } + return _VSTD::move_backward(__first, __m, __last); + } else { + _ForwardIterator __ret = __first; + for (; __n > 0; --__n) { + if (__ret == __last) { + return __last; + } + ++__ret; + } + + // We have an __n-element scratch space from __first to __ret. + // Slide an __n-element window [__trail, __lead) from left to right. + // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) + // over and over; but once __lead reaches __last we needn't bother + // to save the values of elements [__trail, __last). + + auto __trail = __first; + auto __lead = __ret; + while (__trail != __ret) { + if (__lead == __last) { + _VSTD::move(__first, __trail, __ret); + return __ret; + } + ++__trail; + ++__lead; + } + + _ForwardIterator __mid = __first; + while (true) { + if (__lead == __last) { + __trail = _VSTD::move(__mid, __ret, __trail); + _VSTD::move(__first, __mid, __trail); + return __ret; + } + swap(*__mid, *__trail); + ++__mid; + ++__trail; + ++__lead; + if (__mid == __ret) { + __mid = __first; + } + } + } +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H diff --git a/include/__algorithm/shuffle.h b/include/__algorithm/shuffle.h new file mode 100644 index 000000000..7f6ad50e2 --- /dev/null +++ b/include/__algorithm/shuffle.h @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// 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_SHUFFLE_H +#define _LIBCPP___ALGORITHM_SHUFFLE_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__random/uniform_int_distribution.h> +#include <__utility/swap.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer { +public: + __libcpp_debug_randomizer() { + __state = __seed(); + __inc = __state + 0xda3e39cb94b95bdbULL; + __inc = (__inc << 1) | 1; + } + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + _LIBCPP_HIDE_FROM_ABI result_type operator()() { + uint_fast64_t __oldstate = __state; + __state = __oldstate * 6364136223846793005ULL + __inc; + return __oldstate >> 32; + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; } + +private: + uint_fast64_t __state; + uint_fast64_t __inc; + _LIBCPP_HIDE_FROM_ABI static uint_fast64_t __seed() { +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED + return _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED; +#else + static char __x; + return reinterpret_cast(&__x); +#endif + } +}; + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ + || defined(_LIBCPP_BUILDING_LIBRARY) +class _LIBCPP_TYPE_VIS __rs_default; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +class _LIBCPP_TYPE_VIS __rs_default +{ + static unsigned __c_; + + __rs_default(); +public: + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + __rs_default(const __rs_default&); + ~__rs_default(); + + result_type operator()(); + + static _LIBCPP_CONSTEXPR result_type min() {return _Min;} + static _LIBCPP_CONSTEXPR result_type max() {return _Max;} + + friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); +}; + +_LIBCPP_FUNC_VIS __rs_default __rs_get(); + +template +_LIBCPP_DEPRECATED_IN_CXX14 void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + __rs_default __g = __rs_get(); + for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} + +template +_LIBCPP_DEPRECATED_IN_CXX14 void +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, +#ifndef _LIBCPP_CXX03_LANG + _RandomNumberGenerator&& __rand) +#else + _RandomNumberGenerator& __rand) +#endif +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __d = __last - __first; + if (__d > 1) + { + for (--__last; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __rand(__d); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} +#endif + +template + void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, + _UniformRandomNumberGenerator&& __g) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) + { + _Dp __uid; + for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) + { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); + } + } +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SHUFFLE_H diff --git a/include/__algorithm/sift_down.h b/include/__algorithm/sift_down.h new file mode 100644 index 000000000..bf5447698 --- /dev/null +++ b/include/__algorithm/sift_down.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_SIFT_DOWN_H +#define _LIBCPP___ALGORITHM_SIFT_DOWN_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX11 void +__sift_down(_RandomAccessIterator __first, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + _RandomAccessIterator __start) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + // left-child of __start is at 2 * __start + 1 + // right-child of __start is at 2 * __start + 2 + difference_type __child = __start - __first; + + if (__len < 2 || (__len - 2) / 2 < __child) + return; + + __child = 2 * __child + 1; + _RandomAccessIterator __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + if (__comp(*__child_i, *__start)) + // we are, __start is larger than its largest child + return; + + value_type __top(_VSTD::move(*__start)); + do + { + // we are not in heap-order, swap the parent with its largest child + *__start = _VSTD::move(*__child_i); + __start = __child_i; + + if ((__len - 2) / 2 < __child) + break; + + // recompute the child based off of the updated parent + __child = 2 * __child + 1; + __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + } while (!__comp(*__child_i, __top)); + *__start = _VSTD::move(__top); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H diff --git a/include/__algorithm/sort.h b/include/__algorithm/sort.h new file mode 100644 index 000000000..5e09b2800 --- /dev/null +++ b/include/__algorithm/sort.h @@ -0,0 +1,556 @@ +//===----------------------------------------------------------------------===// +// +// 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_SORT_H +#define _LIBCPP___ALGORITHM_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/min_element.h> +#include <__algorithm/partial_sort.h> +#include <__algorithm/unwrap_iter.h> +#include <__config> +#include <__utility/swap.h> +#include + +#if defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) +# include <__algorithm/shuffle.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// stable, 2-3 compares, 0-2 swaps + +template +_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 + { + 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; + } + return __r; +} // x <= y && y <= z + +// stable, 3-6 compares, 0-5 swaps + +template +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; + } + } + } + return __r; +} + +// stable, 4-10 compares, 0-9 swaps + +template +_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(*__x2, *__x1)) + { + swap(*__x1, *__x2); + ++__r; + } + } + } + } + return __r; +} + +// Assumes size > 0 +template +_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 +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 +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; + } +} + +template +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<_Compare>(__first, __first+difference_type(1), --__last, __comp); + return true; + case 4: + _VSTD::__sort4<_Compare>(__first, __first+difference_type(1), __first+difference_type(2), --__last, __comp); + return true; + case 5: + _VSTD::__sort5<_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<_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 +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 __h(__first2, __d); + value_type* __last2 = __first2; + ::new ((void*)__last2) value_type(_VSTD::move(*__first1)); + __d.template __incr(); + 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(); + 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(); + } + } + __h.release(); + } +} + +template +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 && + is_trivially_copy_assignable::value ? 30 : 6; + while (true) + { + __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; + 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; + } + } + } + // 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 +inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { + _Number __log2 = 0; + while (__n > 1) { + __log2++; + __n >>= 1; + } + return __log2; +} + +template +void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __depth_limit = 2 * __log2i(__last - __first); + _VSTD::__introsort<_Compare>(__first, __last, __comp, __depth_limit); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +__sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) +{ + __less __comp; + _VSTD::__sort<__less&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); +} + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&)) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) +#endif +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&)) + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, char*>(char*, char*, __less&)) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) +#endif +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, signed char*>(signed char*, signed char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, short*>(short*, short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, int*>(int*, int*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned*>(unsigned*, unsigned*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long*>(long*, long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long long*>(long long*, long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, float*>(float*, float*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, double*>(double*, double*, __less&)) +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&)) + +_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&)) + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + _LIBCPP_DEBUG_RANDOMIZE_RANGE(__first, __last); + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + if (__libcpp_is_constant_evaluated()) { + _VSTD::__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)); + } +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::sort(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SORT_H diff --git a/include/__algorithm/sort_heap.h b/include/__algorithm/sort_heap.h new file mode 100644 index 000000000..64291ff2e --- /dev/null +++ b/include/__algorithm/sort_heap.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___ALGORITHM_SORT_HEAP_H +#define _LIBCPP___ALGORITHM_SORT_HEAP_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/pop_heap.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include // swap + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 void +__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) + _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::sort_heap(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SORT_HEAP_H diff --git a/include/__algorithm/stable_partition.h b/include/__algorithm/stable_partition.h new file mode 100644 index 000000000..331f0fde7 --- /dev/null +++ b/include/__algorithm/stable_partition.h @@ -0,0 +1,295 @@ +//===----------------------------------------------------------------------===// +// +// 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_STABLE_PARTITION_H +#define _LIBCPP___ALGORITHM_STABLE_PARTITION_H + +#include <__algorithm/rotate.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_ForwardIterator +__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, forward_iterator_tag __fit) +{ + // *__first is known to be false + // __len >= 1 + if (__len == 1) + return __first; + if (__len == 2) + { + _ForwardIterator __m = __first; + if (__pred(*++__m)) + { + swap(*__first, *__m); + return __m; + } + return __first; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_VSTD::move(*__first)); + __d.template __incr(); + ++__t; + _ForwardIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + else + { + ::new ((void*)__t) value_type(_VSTD::move(*__i)); + __d.template __incr(); + ++__t; + } + } + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + __i = __first; + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) + *__i = _VSTD::move(*__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 3 + _ForwardIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _VSTD::advance(__m, __len2); + // recurse on [__first, __m), *__first know to be false + // F????????????????? + // f m l + _ForwardIterator __first_false = _VSTD::__stable_partition<_Predicate&>(__first, __m, __pred, __len2, __p, __fit); + // TTTFFFFF?????????? + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + _ForwardIterator __m1 = __m; + _ForwardIterator __second_false = __last; + _Distance __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????? + // f ff m m1 l + __second_false = _VSTD::__stable_partition<_Predicate&>(__m1, __last, __pred, __len_half, __p, __fit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return _VSTD::rotate(__first_false, __m, __second_false); + // TTTTTTTTFFFFFFFFFF + // | +} + +template +_ForwardIterator +__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, + forward_iterator_tag) +{ + const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // We now have a reduced range [__first, __last) + // *__first is known to be false + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + difference_type __len = _VSTD::distance(__first, __last); + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { + __p = _VSTD::get_temporary_buffer(__len); + __h.reset(__p.first); + } + return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, forward_iterator_tag()); +} + +template +_BidirectionalIterator +__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) +{ + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + if (__len == 2) + { + swap(*__first, *__last); + return __last; + } + if (__len == 3) + { + _BidirectionalIterator __m = __first; + if (__pred(*++__m)) + { + swap(*__first, *__m); + swap(*__m, *__last); + return __last; + } + swap(*__m, *__last); + swap(*__first, *__m); + return __m; + } + if (__len <= __p.second) + { // The buffer is big enough to use + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_VSTD::move(*__first)); + __d.template __incr(); + ++__t; + _BidirectionalIterator __i = __first; + while (++__i != __last) + { + if (__pred(*__i)) + { + *__first = _VSTD::move(*__i); + ++__first; + } + else + { + ::new ((void*)__t) value_type(_VSTD::move(*__i)); + __d.template __incr(); + ++__t; + } + } + // move *__last, known to be true + *__first = _VSTD::move(*__i); + __i = ++__first; + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) + *__i = _VSTD::move(*__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 4 + _BidirectionalIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _VSTD::advance(__m, __len2); + // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false + // F????????????????T + // f m l + _BidirectionalIterator __m1 = __m; + _BidirectionalIterator __first_false = __first; + _Distance __len_half = __len2; + while (!__pred(*--__m1)) + { + if (__m1 == __first) + goto __first_half_done; + --__len_half; + } + // F???TFFF?????????T + // f m1 m l + __first_false = _VSTD::__stable_partition<_Predicate&>(__first, __m1, __pred, __len_half, __p, __bit); +__first_half_done: + // TTTFFFFF?????????T + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + __m1 = __m; + _BidirectionalIterator __second_false = __last; + ++__second_false; + __len_half = __len - __len2; + while (__pred(*__m1)) + { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????T + // f ff m m1 l + __second_false = _VSTD::__stable_partition<_Predicate&>(__m1, __last, __pred, __len_half, __p, __bit); +__second_half_done: + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return _VSTD::rotate(__first_false, __m, __second_false); + // TTTTTTTTFFFFFFFFFF + // | +} + +template +_BidirectionalIterator +__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, + bidirectional_iterator_tag) +{ + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) + { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // __first points to first false, everything prior to __first is already set. + // Either prove [__first, __last) is all false and return __first, or point __last to last true + do + { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + // We now have a reduced range [__first, __last] + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + difference_type __len = _VSTD::distance(__first, __last) + 1; + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) + { + __p = _VSTD::get_temporary_buffer(__len); + __h.reset(__p.first); + } + return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator +stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) +{ + return _VSTD::__stable_partition<_Predicate&>(__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H diff --git a/include/__algorithm/stable_sort.h b/include/__algorithm/stable_sort.h new file mode 100644 index 000000000..4ae17e0e4 --- /dev/null +++ b/include/__algorithm/stable_sort.h @@ -0,0 +1,230 @@ +//===----------------------------------------------------------------------===// +// +// 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_STABLE_SORT_H +#define _LIBCPP___ALGORITHM_STABLE_SORT_H + +#include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/inplace_merge.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/swap.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +void +__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) +{ + typedef typename iterator_traits<_InputIterator1>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__result, __d); + for (; true; ++__result) + { + if (__first1 == __last1) + { + for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + __h.release(); + return; + } + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + __h.release(); + return; + } + if (__comp(*__first2, *__first1)) + { + ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + __d.template __incr(); + ++__first2; + } + else + { + ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + __d.template __incr(); + ++__first1; + } + } +} + +template +void +__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) +{ + for (; __first1 != __last1; ++__result) + { + if (__first2 == __last2) + { + for (; __first1 != __last1; ++__first1, (void) ++__result) + *__result = _VSTD::move(*__first1); + return; + } + if (__comp(*__first2, *__first1)) + { + *__result = _VSTD::move(*__first2); + ++__first2; + } + else + { + *__result = _VSTD::move(*__first1); + ++__first1; + } + } + for (; __first2 != __last2; ++__first2, (void) ++__result) + *__result = _VSTD::move(*__first2); +} + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); + +template +void +__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __first2) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + switch (__len) + { + case 0: + return; + case 1: + ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + return; + case 2: + __destruct_n __d(0); + unique_ptr __h2(__first2, __d); + if (__comp(*--__last1, *__first1)) + { + ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + } + else + { + ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + } + __h2.release(); + return; + } + if (__len <= 8) + { + _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first1 + __l2; + _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); + _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); +} + +template +struct __stable_sort_switch +{ + static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; +}; + +template +void +__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) +{ + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__len) + { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return; + } + if (__len <= static_cast(__stable_sort_switch::value)) + { + _VSTD::__insertion_sort<_Compare>(__first, __last, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first + __l2; + if (__len <= __buff_size) + { + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); + __d.__set(__l2, (value_type*)nullptr); + _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + __d.__set(__len, (value_type*)nullptr); + _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); +// _VSTD::__merge<_Compare>(move_iterator(__buff), +// move_iterator(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __l2), +// move_iterator<_RandomAccessIterator>(__buff + __len), +// __first, __comp); + return; + } + _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +} + +template +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 __buf(0, 0); + unique_ptr __h; + if (__len > static_cast(__stable_sort_switch::value)) + { + __buf = _VSTD::get_temporary_buffer(__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); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + _VSTD::stable_sort(__first, __last, __less::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H diff --git a/include/__algorithm/swap_ranges.h b/include/__algorithm/swap_ranges.h new file mode 100644 index 000000000..2b099c736 --- /dev/null +++ b/include/__algorithm/swap_ranges.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___ALGORITHM_SWAP_RANGES_H +#define _LIBCPP___ALGORITHM_SWAP_RANGES_H + +#include <__config> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + for (; __first1 != __last1; ++__first1, (void)++__first2) + swap(*__first1, *__first2); + return __first2; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H diff --git a/include/__algorithm/transform.h b/include/__algorithm/transform.h new file mode 100644 index 000000000..494cb7128 --- /dev/null +++ b/include/__algorithm/transform.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___ALGORITHM_TRANSFORM_H +#define _LIBCPP___ALGORITHM_TRANSFORM_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) +{ + for (; __first != __last; ++__first, (void) ++__result) + *__result = __op(*__first); + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_TRANSFORM_H diff --git a/include/__algorithm/unique.h b/include/__algorithm/unique.h new file mode 100644 index 000000000..e17ff1567 --- /dev/null +++ b/include/__algorithm/unique.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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_UNIQUE_H +#define _LIBCPP___ALGORITHM_UNIQUE_H + +#include <__algorithm/adjacent_find.h> +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// unique + +template +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) +{ + __first = _VSTD::adjacent_find<_ForwardIterator, _BinaryPredicate&>(__first, __last, __pred); + if (__first != __last) + { + // ... a a ? ... + // f i + _ForwardIterator __i = __first; + for (++__i; ++__i != __last;) + if (!__pred(*__first, *__i)) + *++__first = _VSTD::move(*__i); + ++__first; + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type __v; + return _VSTD::unique(__first, __last, __equal_to<__v>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNIQUE_H diff --git a/include/__algorithm/unique_copy.h b/include/__algorithm/unique_copy.h new file mode 100644 index 000000000..4833ae9b5 --- /dev/null +++ b/include/__algorithm/unique_copy.h @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// 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_UNIQUE_COPY_H +#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H + +#include <__algorithm/comp.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, + input_iterator_tag, output_iterator_tag) +{ + if (__first != __last) + { + typename iterator_traits<_InputIterator>::value_type __t(*__first); + *__result = __t; + ++__result; + while (++__first != __last) + { + if (!__pred(__t, *__first)) + { + __t = *__first; + *__result = __t; + ++__result; + } + } + } + return __result; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator +__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, + forward_iterator_tag, output_iterator_tag) +{ + if (__first != __last) + { + _ForwardIterator __i = __first; + *__result = *__i; + ++__result; + while (++__first != __last) + { + if (!__pred(*__i, *__first)) + { + *__result = *__first; + ++__result; + __i = __first; + } + } + } + return __result; +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, + input_iterator_tag, forward_iterator_tag) +{ + if (__first != __last) + { + *__result = *__first; + while (++__first != __last) + if (!__pred(*__result, *__first)) + *++__result = *__first; + ++__result; + } + return __result; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) +{ + return _VSTD::__unique_copy<_BinaryPredicate&>(__first, __last, __result, __pred, + typename iterator_traits<_InputIterator>::iterator_category(), + typename iterator_traits<_OutputIterator>::iterator_category()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + typedef typename iterator_traits<_InputIterator>::value_type __v; + return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); +} + + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H diff --git a/include/__algorithm/unwrap_iter.h b/include/__algorithm/unwrap_iter.h new file mode 100644 index 000000000..35765330b --- /dev/null +++ b/include/__algorithm/unwrap_iter.h @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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_UNWRAP_ITER_H +#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H + +#include <__config> +#include <__memory/pointer_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// The job of __unwrap_iter is to lower contiguous iterators (such as +// vector::iterator) into pointers, to reduce the number of template +// instantiations and to enable pointer-based optimizations e.g. in std::copy. +// For iterators that are not contiguous, it must be a no-op. +// In debug mode, we don't do this. +// +// __unwrap_iter is non-constexpr for user-defined iterators whose +// `to_address` and/or `operator->` is non-constexpr. This is okay; but we +// try to avoid doing __unwrap_iter in constant-evaluated contexts anyway. +// +// Some algorithms (e.g. std::copy, but not std::sort) need to convert an +// "unwrapped" result back into a contiguous iterator. Since contiguous iterators +// are random-access, we can do this portably using iterator arithmetic; this +// is the job of __rewrap_iter. + +template ::value> +struct __unwrap_iter_impl { + static _LIBCPP_CONSTEXPR _Iter + __apply(_Iter __i) _NOEXCEPT { + return __i; + } +}; + +#if _LIBCPP_DEBUG_LEVEL < 2 + +template +struct __unwrap_iter_impl<_Iter, true> { + static _LIBCPP_CONSTEXPR decltype(_VSTD::__to_address(declval<_Iter>())) + __apply(_Iter __i) _NOEXCEPT { + return _VSTD::__to_address(__i); + } +}; + +#endif // _LIBCPP_DEBUG_LEVEL < 2 + +template > +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +decltype(_Impl::__apply(declval<_Iter>())) +__unwrap_iter(_Iter __i) _NOEXCEPT +{ + return _Impl::__apply(__i); +} + +template +_LIBCPP_HIDE_FROM_ABI +_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result) +{ + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI +_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)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H diff --git a/include/__algorithm/upper_bound.h b/include/__algorithm/upper_bound.h new file mode 100644 index 000000000..c064f1e35 --- /dev/null +++ b/include/__algorithm/upper_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_UPPER_BOUND_H +#define _LIBCPP___ALGORITHM_UPPER_BOUND_H + +#include <__algorithm/comp.h> +#include <__algorithm/half_positive.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +__upper_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(__value_, *__m)) + __len = __l2; + else + { + __first = ++__m; + __len -= __l2 + 1; + } + } + return __first; +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +{ + return _VSTD::__upper_bound<_Compare&>(__first, __last, __value_, __comp); +} + +template +_LIBCPP_NODISCARD_EXT inline +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +{ + return _VSTD::upper_bound(__first, __last, __value_, + __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H diff --git a/include/__availability b/include/__availability new file mode 100644 index 000000000..4652a6fd9 --- /dev/null +++ b/include/__availability @@ -0,0 +1,277 @@ +// -*- 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___AVAILABILITY +#define _LIBCPP___AVAILABILITY + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// Libc++ is shipped by various vendors. In particular, it is used as a system +// library on macOS, iOS and other Apple platforms. In order for users to be +// able to compile a binary that is intended to be deployed to an older version +// of a platform, Clang provides availability attributes [1]. These attributes +// can be placed on declarations and are used to describe the life cycle of a +// symbol in the library. +// +// The main goal is to ensure a compile-time error if a symbol that hasn't been +// introduced in a previously released library is used in a program that targets +// that previously released library. Normally, this would be a load-time error +// when one tries to launch the program against the older library. +// +// For example, the filesystem library was introduced in the dylib in macOS 10.15. +// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their +// program, the compiler would normally not complain (because the required +// declarations are in the headers), but the dynamic loader would fail to find +// the symbols when actually trying to launch the program on macOS 10.13. To +// turn this into a compile-time issue instead, declarations are annotated with +// when they were introduced, and the compiler can produce a diagnostic if the +// program references something that isn't available on the deployment target. +// +// This mechanism is general in nature, and any vendor can add their markup to +// the library (see below). Whenever a new feature is added that requires support +// in the shared library, a macro should be added below to mark this feature +// as unavailable. When vendors decide to ship the feature as part of their +// shared library, they can update the markup appropriately. +// +// Furthermore, many features in the standard library have corresponding +// feature-test macros. When a feature is made unavailable on some deployment +// target, a macro should be defined to signal that it is unavailable. That +// macro can then be picked up when feature-test macros are generated (see +// generate_feature_test_macro_components.py) to make sure that feature-test +// macros don't announce a feature as being implemented if it has been marked +// as unavailable. +// +// Note that this mechanism is disabled by default in the "upstream" libc++. +// Availability annotations are only meaningful when shipping libc++ inside +// a platform (i.e. as a system library), and so vendors that want them should +// turn those annotations on at CMake configuration time. +// +// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability + + +// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY +// for a while. +#if defined(_LIBCPP_DISABLE_AVAILABILITY) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +// Availability markup is disabled when building the library, or when the compiler +// doesn't support the proper attributes. +#if defined(_LIBCPP_BUILDING_LIBRARY) || \ + defined(_LIBCXXABI_BUILDING_LIBRARY) || \ + !__has_feature(attribute_availability_with_strict) || \ + !__has_feature(attribute_availability_in_templates) || \ + !__has_extension(pragma_clang_attribute_external_declaration) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) + + // This controls the availability of std::shared_mutex and std::shared_timed_mutex, + // which were added to the dylib later. +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex + + // These macros control the availability of std::bad_optional_access and + // 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. +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST + + // This controls the availability of std::uncaught_exceptions(). +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS + + // This controls the availability of the sized version of ::operator delete, + // which was added to the dylib later. +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE + + // This controls the availability of the std::future_error exception. +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR + + // This controls the availability of std::type_info's vtable. + // I can't imagine how using std::type_info can work at all if + // this isn't supported. +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + + // This controls the availability of std::locale::category members + // (e.g. std::locale::collate), which are defined in the dylib. +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY + + // This controls the availability of atomic operations on std::shared_ptr + // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared + // lock table located in the dylib. +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR + + // These macros control the availability of all parts of that + // depend on something in the dylib. +# define _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +# 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). +# define _LIBCPP_AVAILABILITY_SYNC +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore + + // 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 +// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + +#elif defined(__APPLE__) + +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macosx,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))) +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex +# endif + +# 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))) +# 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(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(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) + +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ + __attribute__((availability(ios,strict,introduced=6.0))) + +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ + __attribute__((availability(macosx,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(ios,strict,introduced=7.0))) + +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) + +# define _LIBCPP_AVAILABILITY_FILESYSTEM \ + __attribute__((availability(macosx,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(watchos,strict,introduced=6.0))), apply_to=any(function,record))") +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") +# 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_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(ios,strict,introduced=14.0))) \ + __attribute__((availability(tvos,strict,introduced=14.0))) \ + __attribute__((availability(watchos,strict,introduced=7.0))) +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000) +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier +# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch +# 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 +#else + +// ...New vendors can add availability markup here... + +# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" + +#endif + +// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS. +// Those are defined in terms of the availability attributes above, and +// should not be vendor-specific. +#if defined(_LIBCPP_NO_EXCEPTIONS) +# define _LIBCPP_AVAILABILITY_FUTURE +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +#else +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +#endif // _LIBCPP___AVAILABILITY diff --git a/include/__bit/bit_cast.h b/include/__bit/bit_cast.h new file mode 100644 index 000000000..6cfe4d799 --- /dev/null +++ b/include/__bit/bit_cast.h @@ -0,0 +1,38 @@ +// -*- 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___BIT_BIT_CAST_H +#define _LIBCPP___BIT_BIT_CAST_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template && + 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); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_CAST_H diff --git a/include/__bit/byteswap.h b/include/__bit/byteswap.h new file mode 100644 index 000000000..970074ed9 --- /dev/null +++ b/include/__bit/byteswap.h @@ -0,0 +1,55 @@ +// -*- 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___BIT_BYTESWAP_H +#define _LIBCPP___BIT_BYTESWAP_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { + + if constexpr (sizeof(_Tp) == 1) { + return __val; + } else if constexpr (sizeof(_Tp) == 2) { + return __builtin_bswap16(__val); + } else if constexpr (sizeof(_Tp) == 4) { + return __builtin_bswap32(__val); + } else if constexpr (sizeof(_Tp) == 8) { + return __builtin_bswap64(__val); +#ifndef _LIBCPP_HAS_NO_INT128 + } else if constexpr (sizeof(_Tp) == 16) { +#if __has_builtin(__builtin_bswap128) + return __builtin_bswap128(__val); +#else + return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | + static_cast<_Tp>(byteswap(static_cast(__val >> 64))); +#endif // __has_builtin(__builtin_bswap128) +#endif // _LIBCPP_HAS_NO_INT128 + } else { + static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); + } +} + +#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BYTESWAP_H diff --git a/include/__bit_reference b/include/__bit_reference index cce74fb50..a60a5c721 100644 --- a/include/__bit_reference +++ b/include/__bit_reference @@ -10,8 +10,8 @@ #ifndef _LIBCPP___BIT_REFERENCE #define _LIBCPP___BIT_REFERENCE +#include <__bits> #include <__config> -#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -47,6 +47,9 @@ class __bit_reference friend class __bit_const_reference<_Cp>; friend class __bit_iterator<_Cp, false>; public: + _LIBCPP_INLINE_VISIBILITY + __bit_reference(const __bit_reference&) = default; + _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT {return static_cast(*__seg_ & __mask_);} _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT @@ -132,6 +135,9 @@ class __bit_const_reference friend typename _Cp::__self; friend class __bit_iterator<_Cp, true>; public: + _LIBCPP_INLINE_VISIBILITY + __bit_const_reference(const __bit_const_reference&) = default; + _LIBCPP_INLINE_VISIBILITY __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT : __seg_(__x.__seg_), __mask_(__x.__mask_) {} @@ -147,7 +153,7 @@ private: __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT : __seg_(__s), __mask_(__m) {} - __bit_const_reference& operator=(const __bit_const_reference& __x); + __bit_const_reference& operator=(const __bit_const_reference&) = delete; }; // find @@ -233,8 +239,8 @@ __bit_iterator<_Cp, _IsConst> find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) { if (static_cast(__value_)) - return __find_bool_true(__first, static_cast(__last - __first)); - return __find_bool_false(__first, static_cast(__last - __first)); + return _VSTD::__find_bool_true(__first, static_cast(__last - __first)); + return _VSTD::__find_bool_false(__first, static_cast(__last - __first)); } // count @@ -307,8 +313,8 @@ typename __bit_iterator<_Cp, _IsConst>::difference_type count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) { if (static_cast(__value_)) - return __count_bool_true(__first, static_cast(__last - __first)); - return __count_bool_false(__first, static_cast(__last - __first)); + return _VSTD::__count_bool_true(__first, static_cast(__last - __first)); + return _VSTD::__count_bool_false(__first, static_cast(__last - __first)); } // fill_n @@ -332,7 +338,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -362,7 +368,7 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -381,9 +387,9 @@ fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __v if (__n > 0) { if (__value_) - __fill_n_true(__first, __n); + _VSTD::__fill_n_true(__first, __n); else - __fill_n_false(__first, __n); + _VSTD::__fill_n_false(__first, __n); } } @@ -429,8 +435,8 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon // __first.__ctz_ == 0; // do middle words __storage_type __nw = __n / __bits_per_word; - _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), - _VSTD::__to_raw_pointer(__first.__seg_), + _VSTD::memmove(_VSTD::__to_address(__result.__seg_), + _VSTD::__to_address(__first.__seg_), __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; __result.__seg_ += __nw; @@ -532,8 +538,8 @@ __bit_iterator<_Cp, false> copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { if (__first.__ctz_ == __result.__ctz_) - return __copy_aligned(__first, __last, __result); - return __copy_unaligned(__first, __last, __result); + return _VSTD::__copy_aligned(__first, __last, __result); + return _VSTD::__copy_unaligned(__first, __last, __result); } // copy_backward @@ -570,8 +576,8 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C __storage_type __nw = __n / __bits_per_word; __result.__seg_ -= __nw; __last.__seg_ -= __nw; - _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), - _VSTD::__to_raw_pointer(__last.__seg_), + _VSTD::memmove(_VSTD::__to_address(__result.__seg_), + _VSTD::__to_address(__last.__seg_), __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last word @@ -679,8 +685,8 @@ __bit_iterator<_Cp, false> copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { if (__last.__ctz_ == __result.__ctz_) - return __copy_backward_aligned(__first, __last, __result); - return __copy_backward_unaligned(__first, __last, __result); + return _VSTD::__copy_backward_aligned(__first, __last, __result); + return _VSTD::__copy_backward_unaligned(__first, __last, __result); } // move @@ -862,8 +868,8 @@ swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __ __bit_iterator<__C2, false> __first2) { if (__first1.__ctz_ == __first2.__ctz_) - return __swap_ranges_aligned(__first1, __last1, __first2); - return __swap_ranges_unaligned(__first1, __last1, __first2); + return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); + return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2); } // rotate @@ -1077,8 +1083,8 @@ bool equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { if (__first1.__ctz_ == __first2.__ctz_) - return __equal_aligned(__first1, __last1, __first2); - return __equal_unaligned(__first1, __last1, __first2); + return _VSTD::__equal_aligned(__first1, __last1, __first2); + return _VSTD::__equal_unaligned(__first1, __last1, __first2); } template & __it) _NOEXCEPT : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + // When _IsConst=false, we have a user-provided copy constructor, + // so we must also provide a copy assignment operator because + // the implicit generation of a defaulted one is deprecated. + // When _IsConst=true, the assignment operators are + // implicitly generated and trivial. + _LIBCPP_INLINE_VISIBILITY + __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { + __seg_ = __it.__seg_; + __ctz_ = __it.__ctz_; + return *this; + } + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT {return reference(__seg_, __storage_type(1) << __ctz_);} @@ -1277,4 +1300,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_REFERENCE +#endif // _LIBCPP___BIT_REFERENCE diff --git a/include/__bits b/include/__bits new file mode 100644 index 000000000..b565a7823 --- /dev/null +++ b/include/__bits @@ -0,0 +1,145 @@ +// -*- 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___BITS +#define _LIBCPP___BITS + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_COMPILER_MSVC + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } + + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } + + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } + +#else // _LIBCPP_COMPILER_MSVC + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_ctz(unsigned __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + static_assert(sizeof(unsigned long) == 4, ""); + unsigned long __where; + if (_BitScanForward(&__where, __x)) + return static_cast(__where); + return 32; +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_ctz(unsigned long __x) { + static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); + return __ctz(static_cast(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_ctz(unsigned long long __x) { + unsigned long __where; +#if defined(_LIBCPP_HAS_BITSCAN64) + if (_BitScanForward64(&__where, __x)) + return static_cast(__where); +#else + // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. + if (_BitScanForward(&__where, static_cast(__x))) + return static_cast(__where); + if (_BitScanForward(&__where, static_cast(__x >> 32))) + return static_cast(__where + 32); +#endif + return 64; +} + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_clz(unsigned __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + static_assert(sizeof(unsigned long) == 4, ""); + unsigned long __where; + if (_BitScanReverse(&__where, __x)) + return static_cast(31 - __where); + return 32; // Undefined Behavior. +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_clz(unsigned long __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + return __libcpp_clz(static_cast(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __libcpp_clz(unsigned long long __x) { + unsigned long __where; +#if defined(_LIBCPP_HAS_BITSCAN64) + if (_BitScanReverse64(&__where, __x)) + return static_cast(63 - __where); +#else + // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls. + if (_BitScanReverse(&__where, static_cast(__x >> 32))) + return static_cast(63 - (__where + 32)); + if (_BitScanReverse(&__where, static_cast(__x))) + return static_cast(63 - __where); +#endif + return 64; // Undefined Behavior. +} + +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) { + static_assert(sizeof(unsigned) == 4, ""); + return __popcnt(__x); +} + +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) { + static_assert(sizeof(unsigned long) == 4, ""); + return __popcnt(__x); +} + +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) { + static_assert(sizeof(unsigned long long) == 8, ""); + return __popcnt64(__x); +} + +#endif // _LIBCPP_COMPILER_MSVC + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BITS diff --git a/include/__bsd_locale_defaults.h b/include/__bsd_locale_defaults.h index 2ace2a21c..0d6506c62 100644 --- a/include/__bsd_locale_defaults.h +++ b/include/__bsd_locale_defaults.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------- __bsd_locale_defaults.h -----------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/include/__bsd_locale_fallbacks.h b/include/__bsd_locale_fallbacks.h index a807fe039..a5788d977 100644 --- a/include/__bsd_locale_fallbacks.h +++ b/include/__bsd_locale_fallbacks.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------- __bsd_locale_fallbacks.h ----------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,9 +13,9 @@ #ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H #define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H -#include -#include #include +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -30,6 +30,7 @@ decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) return MB_CUR_MAX; } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_btowc_l(int __c, locale_t __l) { @@ -88,6 +89,7 @@ size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __libcpp_locale_guard __current(__l); return mbrlen(__s, __n, __ps); } +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY lconv *__libcpp_localeconv_l(locale_t __l) @@ -96,6 +98,7 @@ lconv *__libcpp_localeconv_l(locale_t __l) return localeconv(); } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, mbstate_t *__ps, locale_t __l) @@ -103,8 +106,9 @@ size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, __libcpp_locale_guard __current(__l); return mbsrtowcs(__dest, __src, __len, __ps); } +#endif -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -114,7 +118,7 @@ int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__forma return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -124,7 +128,7 @@ int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); diff --git a/include/__charconv/chars_format.h b/include/__charconv/chars_format.h new file mode 100644 index 000000000..22e70b56f --- /dev/null +++ b/include/__charconv/chars_format.h @@ -0,0 +1,77 @@ +// -*- 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_CHARS_FORMAT_H +#define _LIBCPP___CHARCONV_CHARS_FORMAT_H + +#include <__config> +#include <__utility/to_underlying.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +enum class _LIBCPP_ENUM_VIS chars_format +{ + scientific = 0x1, + fixed = 0x2, + hex = 0x4, + general = fixed | scientific +}; + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator~(chars_format __x) { + return chars_format(~_VSTD::__to_underlying(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator&(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) & + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator|(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) | + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator^(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) ^ + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator&=(chars_format& __x, chars_format __y) { + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator|=(chars_format& __x, chars_format __y) { + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator^=(chars_format& __x, chars_format __y) { + __x = __x ^ __y; + return __x; +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_CHARS_FORMAT_H diff --git a/include/__charconv/from_chars_result.h b/include/__charconv/from_chars_result.h new file mode 100644 index 000000000..fbd7d5081 --- /dev/null +++ b/include/__charconv/from_chars_result.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___CHARCONV_FROM_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +struct _LIBCPP_TYPE_VIS from_chars_result +{ + const char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H diff --git a/include/__charconv/to_chars_result.h b/include/__charconv/to_chars_result.h new file mode 100644 index 000000000..f515ee312 --- /dev/null +++ b/include/__charconv/to_chars_result.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___CHARCONV_TO_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +struct _LIBCPP_TYPE_VIS to_chars_result +{ + char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_TO_CHARS_RESULT_H diff --git a/include/__chrono/calendar.h b/include/__chrono/calendar.h new file mode 100644 index 000000000..745f7f5cf --- /dev/null +++ b/include/__chrono/calendar.h @@ -0,0 +1,1276 @@ +// -*- 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_CALENDAR_H +#define _LIBCPP___CHRONO_CALENDAR_H + +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include +#include +#include + +#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 +{ + +struct local_t {}; +template +using local_time = time_point; +using local_seconds = local_time; +using local_days = local_time; + +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(__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(__lhs) == static_cast(__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(__lhs) < static_cast(__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(__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(static_cast(__lhs)) - + static_cast(static_cast(__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(__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(__lhs) == static_cast(__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(__lhs) < static_cast(__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(static_cast(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast(__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(__lhs) - static_cast(__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(__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(__lhs) == static_cast(__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(__lhs) < static_cast(__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(__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(__lhs) - static_cast(__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(min()) <= __y && __y <= static_cast(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(__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( + static_cast(__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(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast(__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}; } + + +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(__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(__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(static_cast(__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(__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(__lhs.month()) - static_cast(__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::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast(__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::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + + const int __yr = static_cast(__y) - (__m <= February); + const unsigned __mth = static_cast(__m); + const unsigned __dy = static_cast(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__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(__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(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(__y / __m / 1)} + + days{(__wdi.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= + static_cast((__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(__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 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>; + + 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 (abs(__d))), + __m(duration_cast(abs(__d) - hours())), + __s(duration_cast(abs(__d) - hours() - minutes())), + __f(duration_cast (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(__d)); + } + + constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast(__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/include/__chrono/convert_to_timespec.h b/include/__chrono/convert_to_timespec.h new file mode 100644 index 000000000..0106e6dec --- /dev/null +++ b/include/__chrono/convert_to_timespec.h @@ -0,0 +1,55 @@ +// -*- 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_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/include/__chrono/duration.h b/include/__chrono/duration.h new file mode 100644 index 000000000..b7d88cb52 --- /dev/null +++ b/include/__chrono/duration.h @@ -0,0 +1,615 @@ +// -*- 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_DURATION_H +#define _LIBCPP___CHRONO_DURATION_H + +#include <__config> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template > class _LIBCPP_TEMPLATE_VIS duration; + +template +struct __is_duration : false_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template ::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast(__fd.count())); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast, _ToDuration>()(__fd); +} + +template +struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; +#endif + +template +struct _LIBCPP_TEMPLATE_VIS duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template +class _LIBCPP_TEMPLATE_VIS duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_CXX03_LANG + duration() = default; +#else + duration() {} +#endif + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible::value && + (treat_as_floating_point::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = nullptr) + : __rep_(__r) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = nullptr) + : __rep_(chrono::duration_cast(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator+() const {return typename common_type::type(*this);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator-() const {return typename common_type::type(-__rep_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values::max());} +}; + +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply, hours::period>> days; +typedef duration< int, ratio_multiply, days::period>> weeks; +typedef duration< int, ratio_multiply, days::period>> years; +typedef duration< int, ratio_divide>> months; +#endif +// Duration == + +template +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +} // namespace chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + constexpr chrono::hours operator""h(unsigned long long __h) + { + return chrono::hours(static_cast(__h)); + } + + constexpr chrono::duration> operator""h(long double __h) + { + return chrono::duration>(__h); + } + + + constexpr chrono::minutes operator""min(unsigned long long __m) + { + return chrono::minutes(static_cast(__m)); + } + + constexpr chrono::duration> operator""min(long double __m) + { + return chrono::duration> (__m); + } + + + constexpr chrono::seconds operator""s(unsigned long long __s) + { + return chrono::seconds(static_cast(__s)); + } + + constexpr chrono::duration operator""s(long double __s) + { + return chrono::duration (__s); + } + + + constexpr chrono::milliseconds operator""ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast(__ms)); + } + + constexpr chrono::duration operator""ms(long double __ms) + { + return chrono::duration(__ms); + } + + + constexpr chrono::microseconds operator""us(unsigned long long __us) + { + return chrono::microseconds(static_cast(__us)); + } + + constexpr chrono::duration operator""us(long double __us) + { + return chrono::duration (__us); + } + + + constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast(__ns)); + } + + constexpr chrono::duration operator""ns(long double __ns) + { + return chrono::duration (__ns); + } + +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_DURATION_H diff --git a/include/__chrono/file_clock.h b/include/__chrono/file_clock.h new file mode 100644 index 000000000..cd8758f81 --- /dev/null +++ b/include/__chrono/file_clock.h @@ -0,0 +1,85 @@ +// -*- 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_FILE_CLOCK_H +#define _LIBCPP___CHRONO_FILE_CLOCK_H + +#include <__availability> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template +using file_time = time_point; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + _LIBCPP_EXPORTED_FROM_ABI + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + +#if _LIBCPP_STD_VER > 17 + template + _LIBCPP_HIDE_FROM_ABI + static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + return chrono::sys_time<_Duration>(__t.time_since_epoch()); + } + + template + _LIBCPP_HIDE_FROM_ABI + static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + return chrono::file_time<_Duration>(__t.time_since_epoch()); + } +#endif // _LIBCPP_STD_VER > 17 +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#endif // _LIBCPP___CHRONO_FILE_CLOCK_H diff --git a/include/__chrono/high_resolution_clock.h b/include/__chrono/high_resolution_clock.h new file mode 100644 index 000000000..f5cde4acb --- /dev/null +++ b/include/__chrono/high_resolution_clock.h @@ -0,0 +1,36 @@ +// -*- 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_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H + +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git a/include/__chrono/steady_clock.h b/include/__chrono/steady_clock.h new file mode 100644 index 000000000..5ba911df8 --- /dev/null +++ b/include/__chrono/steady_clock.h @@ -0,0 +1,44 @@ +// -*- 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_STEADY_CLOCK_H +#define _LIBCPP___CHRONO_STEADY_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H diff --git a/include/__chrono/system_clock.h b/include/__chrono/system_clock.h new file mode 100644 index 000000000..9c977d369 --- /dev/null +++ b/include/__chrono/system_clock.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___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 17 + +template +using sys_time = time_point; +using sys_seconds = sys_time; +using sys_days = sys_time; + +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H diff --git a/include/__chrono/time_point.h b/include/__chrono/time_point.h new file mode 100644 index 000000000..c042e1251 --- /dev/null +++ b/include/__chrono/time_point.h @@ -0,0 +1,249 @@ +// -*- 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_TIME_POINT_H +#define _LIBCPP___CHRONO_TIME_POINT_H + +#include <__chrono/duration.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template +class _LIBCPP_TEMPLATE_VIS time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + time_point(const time_point& t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = nullptr) + : __d_(t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} +}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{floor<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{round<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? +__d : -__d; +} +#endif // _LIBCPP_STD_VER > 14 + +// time_point == + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); +} + +// duration operator-(time_point x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_TIME_POINT_H diff --git a/include/__compare/common_comparison_category.h b/include/__compare/common_comparison_category.h new file mode 100644 index 000000000..37a28db1d --- /dev/null +++ b/include/__compare/common_comparison_category.h @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_COMMON_COMPARISON_CATEGORY_H +#define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H + +#include <__compare/ordering.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __comp_detail { + +enum _ClassifyCompCategory : unsigned { + _None, + _PartialOrd, + _WeakOrd, + _StrongOrd, + _CCC_Size +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory __type_to_enum() noexcept { + if (is_same_v<_Tp, partial_ordering>) + return _PartialOrd; + if (is_same_v<_Tp, weak_ordering>) + return _WeakOrd; + if (is_same_v<_Tp, strong_ordering>) + return _StrongOrd; + return _None; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory +__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { + int __seen[_CCC_Size] = {}; + for (auto __type : __types) + ++__seen[__type]; + if (__seen[_None]) + return _None; + if (__seen[_PartialOrd]) + return _PartialOrd; + if (__seen[_WeakOrd]) + return _WeakOrd; + return _StrongOrd; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; + constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; + constexpr _CCC _Cat = __compute_comp_type(__type_kinds); + if constexpr (_Cat == _None) + return void(); + else if constexpr (_Cat == _PartialOrd) + return partial_ordering::equivalent; + else if constexpr (_Cat == _WeakOrd) + return weak_ordering::equivalent; + else if constexpr (_Cat == _StrongOrd) + return strong_ordering::equivalent; + else + static_assert(_False, "unhandled case"); +} +} // namespace __comp_detail + +// [cmp.common], common comparison category type +template +struct _LIBCPP_TEMPLATE_VIS common_comparison_category { + using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); +}; + +template +using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H diff --git a/include/__compare/compare_partial_order_fallback.h b/include/__compare/compare_partial_order_fallback.h new file mode 100644 index 000000000..64937eaf3 --- /dev/null +++ b/include/__compare/compare_partial_order_fallback.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___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/partial_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __compare_partial_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_partial_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK diff --git a/include/__compare/compare_strong_order_fallback.h b/include/__compare/compare_strong_order_fallback.h new file mode 100644 index 000000000..b7abef26e --- /dev/null +++ b/include/__compare/compare_strong_order_fallback.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___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __compare_strong_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_strong_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK diff --git a/include/__compare/compare_three_way.h b/include/__compare/compare_three_way.h new file mode 100644 index 000000000..ddd37890a --- /dev/null +++ b/include/__compare/compare_three_way.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___COMPARE_COMPARE_THREE_WAY_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H + +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +struct _LIBCPP_TEMPLATE_VIS compare_three_way +{ + template + requires three_way_comparable_with<_T1, _T2> + constexpr _LIBCPP_HIDE_FROM_ABI + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u))) + { return _VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u); } + + using is_transparent = void; +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_H diff --git a/include/__compare/compare_three_way_result.h b/include/__compare/compare_three_way_result.h new file mode 100644 index 000000000..14908c6bb --- /dev/null +++ b/include/__compare/compare_three_way_result.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___COMPARE_COMPARE_THREE_WAY_RESULT_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype( + declval<__make_const_lvalue_ref<_Tp>>() <=> declval<__make_const_lvalue_ref<_Up>>(), void() +)> { + using type = decltype(declval<__make_const_lvalue_ref<_Tp>>() <=> declval<__make_const_lvalue_ref<_Up>>()); +}; + +template +struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> { }; + +template +using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H diff --git a/include/__compare/compare_weak_order_fallback.h b/include/__compare/compare_weak_order_fallback.h new file mode 100644 index 000000000..5a1807e69 --- /dev/null +++ b/include/__compare/compare_weak_order_fallback.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___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __compare_weak_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_weak_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK diff --git a/include/__compare/is_eq.h b/include/__compare/is_eq.h new file mode 100644 index 000000000..906cb0709 --- /dev/null +++ b/include/__compare/is_eq.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___COMPARE_IS_EQ_H +#define _LIBCPP___COMPARE_IS_EQ_H + +#include <__compare/ordering.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_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_IS_EQ_H diff --git a/include/__compare/ordering.h b/include/__compare/ordering.h new file mode 100644 index 000000000..d4087bc85 --- /dev/null +++ b/include/__compare/ordering.h @@ -0,0 +1,319 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_ORDERING_H +#define _LIBCPP___COMPARE_ORDERING_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// exposition only +enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { + __less = -1, + __equiv = 0, + __greater = 1 +}; + +enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { + __unordered = -127 +}; + +class partial_ordering; +class weak_ordering; +class strong_ordering; + +template +inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); + +struct _CmpUnspecifiedParam { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} + + template>> + _CmpUnspecifiedParam(_Tp) = delete; +}; + +class partial_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_OrdResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_NCmpResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr bool __is_ordered() const noexcept { + return __value_ != _ValueT(_NCmpResult::__unordered); + } +public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); + } +private: + _ValueT __value_; +}; + +inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); +inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv); +inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); +inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); + +class weak_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); +inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); +inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); + +class strong_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent + : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); +inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_ORDERING_H diff --git a/include/__compare/partial_order.h b/include/__compare/partial_order.h new file mode 100644 index 000000000..cbadfcde7 --- /dev/null +++ b/include/__compare/partial_order.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___COMPARE_PARTIAL_ORDER +#define _LIBCPP___COMPARE_PARTIAL_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __partial_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __partial_order + +inline namespace __cpo { + inline constexpr auto partial_order = __partial_order::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_PARTIAL_ORDER diff --git a/include/__compare/strong_order.h b/include/__compare/strong_order.h new file mode 100644 index 000000000..a0dc07704 --- /dev/null +++ b/include/__compare/strong_order.h @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_STRONG_ORDER +#define _LIBCPP___COMPARE_STRONG_ORDER + +#include <__bit/bit_cast.h> +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __strong_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept + { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = _VSTD::bit_cast(__t); + int32_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = _VSTD::bit_cast(__t); + int64_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || _VSTD::isinf(__t)) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + int __texp, __uexp; + (void)_VSTD::frexp(__t, &__texp); + (void)_VSTD::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); + } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + using _IntType = conditional_t< + sizeof(__t) == sizeof(int32_t), int32_t, conditional_t< + sizeof(__t) == sizeof(int64_t), int64_t, void> + >; + if constexpr (is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return _VSTD::bit_cast<_IntType>(__t) <=> _VSTD::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __strong_order + +inline namespace __cpo { + inline constexpr auto strong_order = __strong_order::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___COMPARE_STRONG_ORDER diff --git a/include/__compare/synth_three_way.h b/include/__compare/synth_three_way.h new file mode 100644 index 000000000..b93d4932c --- /dev/null +++ b/include/__compare/synth_three_way.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___COMPARE_SYNTH_THREE_WAY_H +#define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H + +#include <__compare/ordering.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/boolean_testable.h> +#include <__config> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [expos.only.func] + +_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = + [](const _Tp& __t, const _Up& __u) + requires requires { + { __t < __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + } + { + if constexpr (three_way_comparable_with<_Tp, _Up>) { + return __t <=> __u; + } else { + if (__t < __u) return weak_ordering::less; + if (__u < __t) return weak_ordering::greater; + return weak_ordering::equivalent; + } + }; + +template +using __synth_three_way_result = decltype(__synth_three_way(declval<_Tp&>(), declval<_Up&>())); + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_SYNTH_THREE_WAY_H diff --git a/include/__compare/three_way_comparable.h b/include/__compare/three_way_comparable.h new file mode 100644 index 000000000..548bf17f0 --- /dev/null +++ b/include/__compare/three_way_comparable.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___COMPARE_THREE_WAY_COMPARABLE_H +#define _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H + +#include <__compare/common_comparison_category.h> +#include <__compare/ordering.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept __compares_as = + same_as, _Cat>; + +template +concept three_way_comparable = + __weakly_equality_comparable_with<_Tp, _Tp> && + __partially_ordered_with<_Tp, _Tp> && + requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { + { __a <=> __b } -> __compares_as<_Cat>; + }; + +template +concept three_way_comparable_with = + three_way_comparable<_Tp, _Cat> && + three_way_comparable<_Up, _Cat> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && + __weakly_equality_comparable_with<_Tp, _Up> && + __partially_ordered_with<_Tp, _Up> && + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t <=> __u } -> __compares_as<_Cat>; + { __u <=> __t } -> __compares_as<_Cat>; + }; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H diff --git a/include/__compare/weak_order.h b/include/__compare/weak_order.h new file mode 100644 index 000000000..1286f39b0 --- /dev/null +++ b/include/__compare/weak_order.h @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_WEAK_ORDER +#define _LIBCPP___COMPARE_WEAK_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [cmp.alg] +namespace __weak_order { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) + noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept + { + partial_ordering __po = (__t <=> __u); + if (__po == partial_ordering::less) { + return weak_ordering::less; + } else if (__po == partial_ordering::equivalent) { + return weak_ordering::equivalent; + } else if (__po == partial_ordering::greater) { + return weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()); } + }; +} // namespace __weak_order + +inline namespace __cpo { + inline constexpr auto weak_order = __weak_order::__fn{}; +} // namespace __cpo + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_WEAK_ORDER diff --git a/include/__concepts/arithmetic.h b/include/__concepts/arithmetic.h new file mode 100644 index 000000000..c2f94239a --- /dev/null +++ b/include/__concepts/arithmetic.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___CONCEPTS_ARITHMETIC_H +#define _LIBCPP___CONCEPTS_ARITHMETIC_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concepts.arithmetic], arithmetic concepts + +template +concept integral = is_integral_v<_Tp>; + +template +concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; + +template +concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; + +template +concept floating_point = is_floating_point_v<_Tp>; + +// Concept helpers for the internal type traits for the fundamental types. + +template +concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; +template +concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ARITHMETIC_H diff --git a/include/__concepts/assignable.h b/include/__concepts/assignable.h new file mode 100644 index 000000000..62f39f1c8 --- /dev/null +++ b/include/__concepts/assignable.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___CONCEPTS_ASSIGNABLE_H +#define _LIBCPP___CONCEPTS_ASSIGNABLE_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.assignable] + +template +concept assignable_from = + is_lvalue_reference_v<_Lhs> && + common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && + requires (_Lhs __lhs, _Rhs&& __rhs) { + { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; + }; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ASSIGNABLE_H diff --git a/include/__concepts/boolean_testable.h b/include/__concepts/boolean_testable.h new file mode 100644 index 000000000..c04c30429 --- /dev/null +++ b/include/__concepts/boolean_testable.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___CONCEPTS_BOOLEAN_TESTABLE_H +#define _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concepts.booleantestable] + +template +concept __boolean_testable_impl = convertible_to<_Tp, bool>; + +template +concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { + { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl; +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H diff --git a/include/__concepts/class_or_enum.h b/include/__concepts/class_or_enum.h new file mode 100644 index 000000000..3d28a8ad9 --- /dev/null +++ b/include/__concepts/class_or_enum.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___CONCEPTS_CLASS_OR_ENUM_H +#define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// Whether a type is a class type or enumeration type according to the Core wording. + +template +concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; + +// Work around Clang bug https://llvm.org/PR52970 +template +concept __workaround_52970 = is_class_v<__uncvref_t<_Tp>> || is_union_v<__uncvref_t<_Tp>>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H diff --git a/include/__concepts/common_reference_with.h b/include/__concepts/common_reference_with.h new file mode 100644 index 000000000..119d8fd8d --- /dev/null +++ b/include/__concepts/common_reference_with.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___CONCEPTS_COMMON_REFERENCE_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H + +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.commonref] + +template +concept common_reference_with = + same_as, common_reference_t<_Up, _Tp>> && + convertible_to<_Tp, common_reference_t<_Tp, _Up>> && + convertible_to<_Up, common_reference_t<_Tp, _Up>>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H diff --git a/include/__concepts/common_with.h b/include/__concepts/common_with.h new file mode 100644 index 000000000..ecaa23b63 --- /dev/null +++ b/include/__concepts/common_with.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___CONCEPTS_COMMON_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_WITH_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.common] + +template +concept common_with = + same_as, common_type_t<_Up, _Tp>> && + requires { + static_cast>(declval<_Tp>()); + static_cast>(declval<_Up>()); + } && + common_reference_with< + add_lvalue_reference_t, + add_lvalue_reference_t> && + common_reference_with< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_WITH_H diff --git a/include/__concepts/constructible.h b/include/__concepts/constructible.h new file mode 100644 index 000000000..49986bb24 --- /dev/null +++ b/include/__concepts/constructible.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_CONSTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H + +#include <__concepts/convertible_to.h> +#include <__concepts/destructible.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.constructible] +template +concept constructible_from = + destructible<_Tp> && is_constructible_v<_Tp, _Args...>; + +// [concept.default.init] + +template +concept __default_initializable = requires { ::new _Tp; }; + +template +concept default_initializable = constructible_from<_Tp> && + requires { _Tp{}; } && __default_initializable<_Tp>; + +// [concept.moveconstructible] +template +concept move_constructible = + constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; + +// [concept.copyconstructible] +template +concept copy_constructible = + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to && + constructible_from<_Tp, const _Tp> && convertible_to; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H diff --git a/include/__concepts/convertible_to.h b/include/__concepts/convertible_to.h new file mode 100644 index 000000000..75f5da203 --- /dev/null +++ b/include/__concepts/convertible_to.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___CONCEPTS_CONVERTIBLE_TO_H +#define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H + +#include <__config> +#include <__utility/declval.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.convertible] + +template +concept convertible_to = + is_convertible_v<_From, _To> && + requires { + static_cast<_To>(declval<_From>()); + }; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H diff --git a/include/__concepts/copyable.h b/include/__concepts/copyable.h new file mode 100644 index 000000000..c264b31a2 --- /dev/null +++ b/include/__concepts/copyable.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_COPYABLE_H +#define _LIBCPP___CONCEPTS_COPYABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concepts.object] + +template +concept copyable = + copy_constructible<_Tp> && + movable<_Tp> && + assignable_from<_Tp&, _Tp&> && + assignable_from<_Tp&, const _Tp&> && + assignable_from<_Tp&, const _Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COPYABLE_H diff --git a/include/__concepts/derived_from.h b/include/__concepts/derived_from.h new file mode 100644 index 000000000..acd4ba473 --- /dev/null +++ b/include/__concepts/derived_from.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___CONCEPTS_DERIVED_FROM_H +#define _LIBCPP___CONCEPTS_DERIVED_FROM_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.derived] + +template +concept derived_from = + is_base_of_v<_Bp, _Dp> && + is_convertible_v; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DERIVED_FROM_H diff --git a/include/__concepts/destructible.h b/include/__concepts/destructible.h new file mode 100644 index 000000000..d57824be9 --- /dev/null +++ b/include/__concepts/destructible.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___CONCEPTS_DESTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_DESTRUCTIBLE_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.destructible] + +template +concept destructible = is_nothrow_destructible_v<_Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DESTRUCTIBLE_H diff --git a/include/__concepts/different_from.h b/include/__concepts/different_from.h new file mode 100644 index 000000000..c8560baf8 --- /dev/null +++ b/include/__concepts/different_from.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___CONCEPTS_DIFFERENT_FROM_H +#define _LIBCPP___CONCEPTS_DIFFERENT_FROM_H + +#include <__concepts/same_as.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept __different_from = !same_as, remove_cvref_t<_Up>>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DIFFERENT_FROM_H diff --git a/include/__concepts/equality_comparable.h b/include/__concepts/equality_comparable.h new file mode 100644 index 000000000..064143b89 --- /dev/null +++ b/include/__concepts/equality_comparable.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___CONCEPTS_EQUALITY_COMPARABLE_H +#define _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/common_reference_with.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.equalitycomparable] + +template +concept __weakly_equality_comparable_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t == __u } -> __boolean_testable; + { __t != __u } -> __boolean_testable; + { __u == __t } -> __boolean_testable; + { __u != __t } -> __boolean_testable; + }; + +template +concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; + +template +concept equality_comparable_with = + equality_comparable<_Tp> && equality_comparable<_Up> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + equality_comparable< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __weakly_equality_comparable_with<_Tp, _Up>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H diff --git a/include/__concepts/invocable.h b/include/__concepts/invocable.h new file mode 100644 index 000000000..e528258e3 --- /dev/null +++ b/include/__concepts/invocable.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___CONCEPTS_INVOCABLE_H +#define _LIBCPP___CONCEPTS_INVOCABLE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.invocable] + +template +concept invocable = requires(_Fn&& __fn, _Args&&... __args) { + _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving +}; + +// [concept.regular.invocable] + +template +concept regular_invocable = invocable<_Fn, _Args...>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_INVOCABLE_H diff --git a/include/__concepts/movable.h b/include/__concepts/movable.h new file mode 100644 index 000000000..fd8c2e7fa --- /dev/null +++ b/include/__concepts/movable.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_MOVABLE_H +#define _LIBCPP___CONCEPTS_MOVABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/swappable.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concepts.object] + +template +concept movable = + is_object_v<_Tp> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp> && + swappable<_Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_MOVABLE_H diff --git a/include/__concepts/predicate.h b/include/__concepts/predicate.h new file mode 100644 index 000000000..491a7d6c7 --- /dev/null +++ b/include/__concepts/predicate.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___CONCEPTS_PREDICATE_H +#define _LIBCPP___CONCEPTS_PREDICATE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/invocable.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.predicate] + +template +concept predicate = + regular_invocable<_Fn, _Args...> && __boolean_testable>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_PREDICATE_H diff --git a/include/__concepts/regular.h b/include/__concepts/regular.h new file mode 100644 index 000000000..e8a87c97f --- /dev/null +++ b/include/__concepts/regular.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___CONCEPTS_REGULAR_H +#define _LIBCPP___CONCEPTS_REGULAR_H + +#include <__concepts/equality_comparable.h> +#include <__concepts/semiregular.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.object] + +template +concept regular = semiregular<_Tp> && equality_comparable<_Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_REGULAR_H diff --git a/include/__concepts/relation.h b/include/__concepts/relation.h new file mode 100644 index 000000000..fa7e5d17d --- /dev/null +++ b/include/__concepts/relation.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___CONCEPTS_RELATION_H +#define _LIBCPP___CONCEPTS_RELATION_H + +#include <__concepts/predicate.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.relation] + +template +concept relation = + predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && + predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; + +// [concept.equiv] + +template +concept equivalence_relation = relation<_Rp, _Tp, _Up>; + +// [concept.strictweakorder] + +template +concept strict_weak_order = relation<_Rp, _Tp, _Up>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_RELATION_H diff --git a/include/__concepts/same_as.h b/include/__concepts/same_as.h new file mode 100644 index 000000000..ee86c44ea --- /dev/null +++ b/include/__concepts/same_as.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___CONCEPTS_SAME_AS_H +#define _LIBCPP___CONCEPTS_SAME_AS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.same] + +template +concept __same_as_impl = _IsSame<_Tp, _Up>::value; + +template +concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SAME_AS_H diff --git a/include/__concepts/semiregular.h b/include/__concepts/semiregular.h new file mode 100644 index 000000000..4797fc7ea --- /dev/null +++ b/include/__concepts/semiregular.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___CONCEPTS_SEMIREGULAR_H +#define _LIBCPP___CONCEPTS_SEMIREGULAR_H + +#include <__concepts/constructible.h> +#include <__concepts/copyable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.object] + +template +concept semiregular = copyable<_Tp> && default_initializable<_Tp>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SEMIREGULAR_H diff --git a/include/__concepts/swappable.h b/include/__concepts/swappable.h new file mode 100644 index 000000000..6b8cf82b7 --- /dev/null +++ b/include/__concepts/swappable.h @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_SWAPPABLE_H +#define _LIBCPP___CONCEPTS_SWAPPABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/class_or_enum.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.swappable] + +namespace ranges { +namespace __swap { + + template + void swap(_Tp&, _Tp&) = delete; + + template + concept __unqualified_swappable_with = + (__class_or_enum> || __class_or_enum>) && + requires(_Tp&& __t, _Up&& __u) { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + }; + + struct __fn; + + template + concept __swappable_arrays = + !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && + extent_v<_Tp> == extent_v<_Up> && + requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { + __swap(__t[0], __u[0]); + }; + + template + concept __exchangeable = + !__unqualified_swappable_with<_Tp&, _Tp&> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp>; + + struct __fn { + // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... + // *The name `swap` is used here unqualified. + template + requires __unqualified_swappable_with<_Tp, _Up> + constexpr void operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + } + + // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... + template + requires __swappable_arrays<_Tp, _Up, _Size> + constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const + noexcept(noexcept((*this)(*__t, *__u))) + { + // TODO(cjdb): replace with `ranges::swap_ranges`. + for (size_t __i = 0; __i < _Size; ++__i) { + (*this)(__t[__i], __u[__i]); + } + } + + // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... + template<__exchangeable _Tp> + constexpr void operator()(_Tp& __x, _Tp& __y) const + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) + { + __y = _VSTD::exchange(__x, _VSTD::move(__y)); + } + }; +} // namespace __swap + +inline namespace __cpo { + inline constexpr auto swap = __swap::__fn{}; +} // namespace __cpo +} // namespace ranges + +template +concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; + +template +concept swappable_with = + common_reference_with<_Tp, _Up> && + requires(_Tp&& __t, _Up&& __u) { + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); + }; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SWAPPABLE_H diff --git a/include/__concepts/totally_ordered.h b/include/__concepts/totally_ordered.h new file mode 100644 index 000000000..58dcb42be --- /dev/null +++ b/include/__concepts/totally_ordered.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___CONCEPTS_TOTALLY_ORDERED_H +#define _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/equality_comparable.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [concept.totallyordered] + +template +concept __partially_ordered_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t < __u } -> __boolean_testable; + { __t > __u } -> __boolean_testable; + { __t <= __u } -> __boolean_testable; + { __t >= __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + { __u > __t } -> __boolean_testable; + { __u <= __t } -> __boolean_testable; + { __u >= __t } -> __boolean_testable; + }; + +template +concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; + +template +concept totally_ordered_with = + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + totally_ordered< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __partially_ordered_with<_Tp, _Up>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H diff --git a/include/__config b/include/__config index 044cd0ceb..458d0c1b8 100644 --- a/include/__config +++ b/include/__config @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- __config ---------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,6 +10,8 @@ #ifndef _LIBCPP_CONFIG #define _LIBCPP_CONFIG +#include <__config_site> + #if defined(_MSC_VER) && !defined(__clang__) # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -22,23 +24,13 @@ #ifdef __cplusplus -#ifdef __GNUC__ -# define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) -// The _GNUC_VER_NEW macro better represents the new GCC versioning scheme -// introduced in GCC 5.0. -# define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__) -#else -# define _GNUC_VER 0 -# define _GNUC_VER_NEW 0 -#endif - -#define _LIBCPP_VERSION 10000 +#define _LIBCPP_VERSION 14000 #ifndef _LIBCPP_ABI_VERSION # define _LIBCPP_ABI_VERSION 1 #endif -#ifndef __STDC_HOSTED__ +#if __STDC_HOSTED__ == 0 # define _LIBCPP_FREESTANDING #endif @@ -49,10 +41,12 @@ # 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 18 // current year, or date of c++2a ratification +# define _LIBCPP_STD_VER 21 // current year, or date of c++2b ratification # endif -#endif // _LIBCPP_STD_VER +#endif // _LIBCPP_STD_VER #if defined(__ELF__) # define _LIBCPP_OBJECT_FORMAT_ELF 1 @@ -63,7 +57,7 @@ #elif defined(__wasm__) # define _LIBCPP_OBJECT_FORMAT_WASM 1 #else -# error Unknown object file format + // ... add new file formats here ... #endif #if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 @@ -80,21 +74,23 @@ # 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 -// Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr -// provided under the alternate keyword __nullptr, which changes the mangling -// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. -# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR -// Define the `pointer_safety` enum as a C++11 strongly typed enumeration -// instead of as a class simulating an enum. If this option is enabled -// `pointer_safety` and `get_pointer_safety()` will no longer be available -// in C++03. -# define _LIBCPP_ABI_POINTER_SAFETY_ENUM_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 +// 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 // 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 +// Give reverse_iterator 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 // 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 @@ -102,6 +98,26 @@ # 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 +// Re-worked external template instantiations for std::string with a focus on +// performance and fast-path inlining. +# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION +// Enable clang::trivial_abi on std::unique_ptr. +# 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 +// 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_DO_NOT_EXPORT_BASIC_STRING_COMMON +// Remove vector base class +# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -118,9 +134,33 @@ # endif #endif -#ifdef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR -#error "_LIBCPP_TRIVIAL_PAIR_COPY_CTOR" is no longer supported. \ - use _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR instead +// 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 +// 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 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_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y @@ -170,11 +210,12 @@ #define __has_include(...) 0 #endif -#if defined(__clang__) -# define _LIBCPP_COMPILER_CLANG -# ifndef __apple_build_version__ -# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) -# 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) @@ -220,17 +261,21 @@ # endif // defined(__GLIBC_PREREQ) #endif // defined(__linux__) +#if defined(__MVS__) +# include // for __NATIVE_ASCII_F +#endif + #ifdef __LITTLE_ENDIAN__ # if __LITTLE_ENDIAN__ # define _LIBCPP_LITTLE_ENDIAN # endif // __LITTLE_ENDIAN__ -#endif // __LITTLE_ENDIAN__ +#endif // __LITTLE_ENDIAN__ #ifdef __BIG_ENDIAN__ # if __BIG_ENDIAN__ # define _LIBCPP_BIG_ENDIAN # endif // __BIG_ENDIAN__ -#endif // __BIG_ENDIAN__ +#endif // __BIG_ENDIAN__ #ifdef __BYTE_ORDER__ # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -248,20 +293,16 @@ # else // _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_BIG_ENDIAN # endif // _BYTE_ORDER == _LITTLE_ENDIAN -# ifndef __LONG_LONG_SUPPORTED -# define _LIBCPP_HAS_NO_LONG_LONG -# endif // __LONG_LONG_SUPPORTED -#endif // __FreeBSD__ +#endif // __FreeBSD__ -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) # include # if _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN # else // _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_BIG_ENDIAN # endif // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_HAS_QUICK_EXIT -#endif // __NetBSD__ +#endif // defined(__NetBSD__) || defined(__OpenBSD__) #if defined(_WIN32) # define _LIBCPP_WIN32API @@ -302,18 +343,56 @@ # endif #endif // __sun__ -#if defined(__CloudABI__) - // Certain architectures provide arc4random(). Prefer using - // arc4random() over /dev/{u,}random to make it possible to obtain - // random data even when using sandboxing mechanisms such as chroots, - // Capsicum, etc. +#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. +// +// _LIBCPP_USING_DEV_RANDOM +// Read entropy from the given file, by default `/dev/urandom`. +// If a token is provided, it is assumed to be the path to a file +// to read entropy from. This is the default behavior if nothing +// else is specified. This implementation requires storing state +// inside `std::random_device`. +// +// _LIBCPP_USING_ARC4_RANDOM +// Use arc4random(). This allows obtaining random data even when +// using sandboxing mechanisms. On some platforms like Apple, this +// is the recommended source of entropy for user-space programs. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_GETENTROPY +// Use getentropy(). +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_FUCHSIA_CPRNG +// Use Fuchsia's zx_cprng_draw() system call, which is specified to +// deliver high-quality entropy and cannot fail. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_NACL_RANDOM +// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, +// including accesses to the special files under `/dev`. This implementation +// uses the NaCL syscall `nacl_secure_random_init()` to get entropy. +// When this option is used, the token passed to `std::random_device`'s +// constructor *must* be "/dev/urandom" -- anything else is an error. +// +// _LIBCPP_USING_WIN32_RANDOM +// 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(__Fuchsia__) || defined(__wasi__) +#elif defined(__wasi__) # define _LIBCPP_USING_GETENTROPY +#elif defined(__Fuchsia__) +# define _LIBCPP_USING_FUCHSIA_CPRNG #elif defined(__native_client__) - // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, - // including accesses to the special files under /dev. C++11's - // std::random_device is instead exposed through a NaCl syscall. # define _LIBCPP_USING_NACL_RANDOM #elif defined(_LIBCPP_WIN32API) # define _LIBCPP_USING_WIN32_RANDOM @@ -330,7 +409,7 @@ # else // __BYTE_ORDER == __BIG_ENDIAN # error unable to determine endian # endif -#endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) +#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"))) @@ -338,51 +417,90 @@ # define _LIBCPP_NO_CFI #endif -#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +// 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 -# define _LIBCPP_HAS_C11_FEATURES -# elif defined(__Fuchsia__) || defined(__wasi__) +# 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 +# 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 -# define _LIBCPP_HAS_C11_FEATURES +# 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_C11_FEATURES +# 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 -# define _LIBCPP_HAS_C11_FEATURES # endif -# endif // __linux__ +# 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) +#elif defined(_LIBCPP_COMPILER_CLANG_BASED) # define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) #else -// This definition is potentially buggy, but it's only taken with GCC in C++03, -// which we barely support anyway. See llvm.org/PR39713 -# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp) +# error "We don't know a correct way to implement alignof(T) in C++03 outside of Clang" #endif #define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) -#if defined(_LIBCPP_COMPILER_CLANG) +#if defined(_LIBCPP_COMPILER_CLANG_BASED) -// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for -// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility. -#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ - (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)) || \ - defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) -#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +#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 #if __has_feature(cxx_alignas) @@ -398,12 +516,8 @@ typedef __char16_t char16_t; typedef __char32_t char32_t; #endif -#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS) -#define _LIBCPP_NO_EXCEPTIONS -#endif - -#if !(__has_feature(cxx_rtti)) && !defined(_LIBCPP_NO_RTTI) -#define _LIBCPP_NO_RTTI +#if !__has_feature(cxx_exceptions) +# define _LIBCPP_NO_EXCEPTIONS #endif #if !(__has_feature(cxx_strong_enums)) @@ -416,10 +530,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NORETURN __attribute__ ((noreturn)) #endif -#if !(__has_feature(cxx_lambdas)) -#define _LIBCPP_HAS_NO_LAMBDAS -#endif - #if !(__has_feature(cxx_nullptr)) # if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR) # define nullptr __nullptr @@ -428,18 +538,6 @@ typedef __char32_t char32_t; # endif #endif -#if !(__has_feature(cxx_rvalue_references)) -#define _LIBCPP_HAS_NO_RVALUE_REFERENCES -#endif - -#if !(__has_feature(cxx_auto_type)) -#define _LIBCPP_HAS_NO_AUTO_TYPE -#endif - -#if !(__has_feature(cxx_variadic_templates)) -#define _LIBCPP_HAS_NO_VARIADICS -#endif - // Objective-C++ features (opt-in) #if __has_feature(objc_arc) #define _LIBCPP_HAS_OBJC_ARC @@ -449,43 +547,29 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_OBJC_ARC_WEAK #endif -#if !(__has_feature(cxx_relaxed_constexpr)) -#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR +#if __has_extension(blocks) +# define _LIBCPP_HAS_EXTENSION_BLOCKS #endif -#if !(__has_feature(cxx_variable_templates)) -#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__) +# define _LIBCPP_HAS_BLOCKS_RUNTIME #endif #if !(__has_feature(cxx_noexcept)) #define _LIBCPP_HAS_NO_NOEXCEPT #endif -#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) +#if !__has_feature(address_sanitizer) #define _LIBCPP_HAS_NO_ASAN #endif // Allow for build-time disabling of unsigned integer sanitization -#if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize) +#if __has_attribute(no_sanitize) #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) #endif -#if __has_builtin(__builtin_launder) -#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER -#endif - -#if !__is_identifier(__has_unique_object_representations) -#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS -#endif - #define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) -// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1 -#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \ - (defined(__apple_build_version__) && __apple_build_version__ < 10010000) -#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS -#endif - #define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ #elif defined(_LIBCPP_COMPILER_GCC) @@ -495,32 +579,14 @@ typedef __char32_t char32_t; #define _LIBCPP_NORETURN __attribute__((noreturn)) -#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS) -#define _LIBCPP_NO_EXCEPTIONS +#if !defined(__EXCEPTIONS) +# define _LIBCPP_NO_EXCEPTIONS #endif -// Determine if GCC supports relaxed constexpr -#if !defined(__cpp_constexpr) || __cpp_constexpr < 201304L -#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR -#endif - -// GCC 5 supports variable templates -#if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L -#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES -#endif - -#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__) +#if !defined(__SANITIZE_ADDRESS__) #define _LIBCPP_HAS_NO_ASAN #endif -#if _GNUC_VER >= 700 -#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER -#endif - -#if _GNUC_VER >= 700 -#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS -#endif - #define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) #define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ @@ -535,8 +601,6 @@ typedef __char32_t char32_t; #error "MSVC versions prior to Visual Studio 2015 are not supported" #endif -#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR -#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #define __alignof__ __alignof #define _LIBCPP_NORETURN __declspec(noreturn) #define _ALIGNAS(x) __declspec(align(x)) @@ -560,7 +624,6 @@ typedef __char32_t char32_t; #define _LIBCPP_NORETURN __attribute__((noreturn)) #define _LIBCPP_HAS_NO_UNICODE_CHARS -#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #if defined(_AIX) #define __MULTILOCALE_API @@ -615,6 +678,7 @@ typedef __char32_t char32_t; #define _LIBCPP_HIDDEN #define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS #define _LIBCPP_TEMPLATE_VIS +#define _LIBCPP_TEMPLATE_DATA_VIS #define _LIBCPP_ENUM_VIS #endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) @@ -664,6 +728,14 @@ typedef __char32_t char32_t; # 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 + #ifndef _LIBCPP_EXPORTED_FROM_ABI # if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) # define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default"))) @@ -693,7 +765,7 @@ typedef __char32_t char32_t; #endif #ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS -# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__visibility__("default"))) # else # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS @@ -727,16 +799,6 @@ typedef __char32_t char32_t; # endif #endif -#ifndef _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT -# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos. -# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 0 -#else -// TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398 -// And we should consider defaulting to OFF. -# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 1 -#endif -#endif - #ifndef _LIBCPP_HIDE_FROM_ABI # if _LIBCPP_HIDE_FROM_ABI_PER_TU # define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE @@ -761,10 +823,10 @@ typedef __char32_t char32_t; // 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_ABI_NAMESPACE +#define _VSTD std _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 #define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { #else @@ -777,10 +839,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD #define _VSTD_FS _VSTD::__fs::filesystem -#ifndef _LIBCPP_PREFERRED_OVERLOAD -# if __has_attribute(__enable_if__) -# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) -# endif +#if __has_attribute(__enable_if__) +# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) #endif #ifndef _LIBCPP_HAS_NO_NOEXCEPT @@ -794,7 +854,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS typedef unsigned short char16_t; typedef unsigned int char32_t; -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +#endif #ifndef __SIZEOF_INT128__ #define _LIBCPP_HAS_NO_INT128 @@ -803,7 +863,7 @@ typedef unsigned int char32_t; #ifdef _LIBCPP_CXX03_LANG # define static_assert(...) _Static_assert(__VA_ARGS__) # define decltype(...) __decltype(__VA_ARGS__) -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_CXX03_LANG #ifdef _LIBCPP_CXX03_LANG # define _LIBCPP_CONSTEXPR @@ -811,16 +871,14 @@ typedef unsigned int char32_t; # define _LIBCPP_CONSTEXPR constexpr #endif -#ifdef _LIBCPP_CXX03_LANG -# define _LIBCPP_DEFAULT {} +#ifndef __cpp_consteval +# define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR #else -# define _LIBCPP_DEFAULT = default; +# define _LIBCPP_CONSTEVAL consteval #endif -#ifdef _LIBCPP_CXX03_LANG -# define _LIBCPP_EQUAL_DELETE -#else -# define _LIBCPP_EQUAL_DELETE = delete +#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_concepts) || __cpp_concepts < 201907L +#define _LIBCPP_HAS_NO_CONCEPTS #endif #ifdef __GNUC__ @@ -829,15 +887,10 @@ typedef unsigned int char32_t; # define _LIBCPP_NOALIAS #endif -#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ - (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions -# define _LIBCPP_EXPLICIT explicit +#if __has_attribute(using_if_exists) +# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists)) #else -# define _LIBCPP_EXPLICIT -#endif - -#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) -#define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE +# define _LIBCPP_USING_IF_EXISTS #endif #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS @@ -851,46 +904,67 @@ typedef unsigned int char32_t; #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 +#endif // _LIBCPP_HAS_NO_STRONG_ENUMS -#ifdef _LIBCPP_DEBUG -# if _LIBCPP_DEBUG == 0 +// _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 # else # error Supported values for _LIBCPP_DEBUG are 0 and 1 # endif -# if !defined(_LIBCPP_BUILDING_LIBRARY) -# define _LIBCPP_EXTERN_TEMPLATE(...) + +# if _LIBCPP_DEBUG_LEVEL >= 2 && !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY # endif -#endif -#ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE -#define _LIBCPP_EXTERN_TEMPLATE(...) -#define _LIBCPP_EXTERN_TEMPLATE2(...) -#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) +# endif -#ifndef _LIBCPP_EXTERN_TEMPLATE -#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; -#endif - -#ifndef _LIBCPP_EXTERN_TEMPLATE2 -#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__; +// 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 ). 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__) || defined(__CloudABI__) + defined(__sun__) || defined(__NetBSD__) #define _LIBCPP_LOCALE__L_EXTENSIONS 1 #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) -# define _LIBCPP_HAS_CATOPEN 1 -# endif -#endif - #ifdef __FreeBSD__ #define _DECLARE_C99_LDBL_MATH 1 #endif @@ -903,18 +977,12 @@ typedef unsigned int char32_t; // 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(__APPLE__) -# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ -# endif -#endif // defined(__APPLE__) - -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ - (defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \ - (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)) +#if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \ + (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606) # define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION #endif @@ -927,7 +995,7 @@ typedef unsigned int char32_t; #endif #if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t) -#define _LIBCPP_NO_HAS_CHAR8_T +#define _LIBCPP_HAS_NO_CHAR8_T #endif // Deprecation macros. @@ -964,18 +1032,29 @@ typedef unsigned int char32_t; # define _LIBCPP_DEPRECATED_IN_CXX17 #endif -// Macros to enter and leave a state where deprecation warnings are suppressed. -#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) && \ - (defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC)) -# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") -# define _LIBCPP_SUPPRESS_DEPRECATED_POP \ - _Pragma("GCC diagnostic pop") +#if _LIBCPP_STD_VER > 17 +# define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX20 #endif -#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) -# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH -# define _LIBCPP_SUPPRESS_DEPRECATED_POP + +#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 _LIBCPP_STD_VER <= 11 @@ -984,72 +1063,50 @@ typedef unsigned int char32_t; # define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit #endif -#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#if _LIBCPP_STD_VER > 11 # define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr #else # define _LIBCPP_CONSTEXPR_AFTER_CXX11 #endif -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#if _LIBCPP_STD_VER > 14 # define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr #else # define _LIBCPP_CONSTEXPR_AFTER_CXX14 #endif -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#if _LIBCPP_STD_VER > 17 # define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr #else # define _LIBCPP_CONSTEXPR_AFTER_CXX17 #endif -// The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other -// NODISCARD macros to the correct attribute. #if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) -# define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]] -#elif defined(_LIBCPP_COMPILER_CLANG) && !defined(_LIBCPP_CXX03_LANG) -# define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]] +# 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_ATTRIBUTE +# 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_ATTRIBUTE +# 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_ATTRIBUTE +# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD #else # define _LIBCPP_NODISCARD_AFTER_CXX17 #endif -#if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) -# define _LIBCPP_INLINE_VAR inline -#else -# define _LIBCPP_INLINE_VAR -#endif - -#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES -# define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) -#else -# define _LIBCPP_EXPLICIT_MOVE(x) (x) -#endif - -#ifndef _LIBCPP_CONSTEXPR_IF_NODEBUG -#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) -#define _LIBCPP_CONSTEXPR_IF_NODEBUG -#else -#define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr -#endif -#endif - #if __has_attribute(no_destroy) # define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) #else @@ -1057,22 +1114,17 @@ typedef unsigned int char32_t; #endif #ifndef _LIBCPP_HAS_NO_ASAN -_LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( +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. -// g++ and cl.exe have RTTI on by default and define a macro when it is. -// g++ only defines the macro in 4.3.2 and onwards. -#if !defined(_LIBCPP_NO_RTTI) -# if defined(__GNUC__) && \ - ((__GNUC__ >= 5) || \ - (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && \ - !defined(__GXX_RTTI) -# define _LIBCPP_NO_RTTI -# elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI) -# define _LIBCPP_NO_RTTI -# endif +#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 #ifndef _LIBCPP_WEAK @@ -1085,15 +1137,19 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \ !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) # if defined(__FreeBSD__) || \ - defined(__Fuchsia__) || \ defined(__wasi__) || \ defined(__NetBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NuttX__) || \ defined(__linux__) || \ defined(__GNU__) || \ defined(__APPLE__) || \ - defined(__CloudABI__) || \ defined(__sun__) || \ - (defined(__MINGW32__) && __has_include()) + 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 @@ -1127,10 +1183,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( _LIBCPP_HAS_NO_THREADS is defined. #endif -#if defined(__STDCPP_THREADS__) && defined(_LIBCPP_HAS_NO_THREADS) -#error _LIBCPP_HAS_NO_THREADS cannot be set when __STDCPP_THREADS__ is set. -#endif - #if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__) #define __STDCPP_THREADS__ 1 #endif @@ -1146,6 +1198,7 @@ _LIBCPP_FUNC_VIS extern "C" 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 @@ -1158,54 +1211,33 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( // // TODO(EricWF): This is potentially true for some pthread implementations // as well. -#if defined(_LIBCPP_HAS_THREAD_API_WIN32) +#if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \ + defined(_LIBCPP_HAS_THREAD_API_WIN32) # define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION #endif -// Systems that use capability-based security (FreeBSD with Capsicum, -// Nuxi CloudABI) may only provide local filesystem access (using *at()). -// Functions like open(), rename(), unlink() and stat() should not be -// used, as they attempt to access the global filesystem namespace. -#ifdef __CloudABI__ -#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE -#endif - -// CloudABI is intended for running networked services. Processes do not -// have standard input and output channels. -#ifdef __CloudABI__ -#define _LIBCPP_HAS_NO_STDIN -#define _LIBCPP_HAS_NO_STDOUT -#endif - // Some systems do not provide gets() in their C library, for security reasons. -#ifndef _LIBCPP_C_HAS_NO_GETS -# if defined(_LIBCPP_MSVCRT) || \ - (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) -# define _LIBCPP_C_HAS_NO_GETS -# endif +#if defined(_LIBCPP_MSVCRT) || \ + (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || \ + defined(__OpenBSD__) +# define _LIBCPP_C_HAS_NO_GETS #endif -#if defined(__BIONIC__) || defined(__CloudABI__) || \ - defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) +#if defined(__BIONIC__) || defined(__NuttX__) || \ + defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE #endif -// Thread-unsafe functions such as strtok() and localtime() -// are not available. -#ifdef __CloudABI__ -#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS -#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(_LIBCPP_HAS_C_ATOMIC_IMP) && \ - !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \ - !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)) \ - || defined(_LIBCPP_HAS_NO_THREADS) +#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 @@ -1224,33 +1256,26 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # 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. -# if !defined(_LIBCPP_OBJECT_FORMAT_COFF) +// 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 # 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 + #if __has_attribute(require_constant_initialization) # define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) #else # define _LIBCPP_SAFE_STATIC #endif -#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 -#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF -#endif - -#if !__has_builtin(__builtin_is_constant_evaluated) && _GNUC_VER < 900 -#define _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED -#endif - -#if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) -# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) -# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS -# endif -#endif - #if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS) # define _LIBCPP_DIAGNOSE_WARNING(...) \ __attribute__((diagnose_if(__VA_ARGS__, "warning"))) @@ -1266,7 +1291,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_FALLTHROUGH() [[fallthrough]] #elif __has_cpp_attribute(clang::fallthrough) # define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]] -#elif __has_attribute(fallthough) || _GNUC_VER >= 700 +#elif __has_attribute(__fallthrough__) # define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) #else # define _LIBCPP_FALLTHROUGH() ((void)0) @@ -1278,14 +1303,27 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_NODEBUG #endif -#ifndef _LIBCPP_NODEBUG_TYPE -#if __has_attribute(__nodebug__) && \ - (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900) -#define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug)) +#if __has_attribute(__standalone_debug__) +#define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__)) #else -#define _LIBCPP_NODEBUG_TYPE +#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 + +// 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 -#endif // !defined(_LIBCPP_NODEBUG_TYPE) #if defined(_LIBCPP_ABI_MICROSOFT) && \ (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases)) @@ -1296,133 +1334,21 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) #define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR -#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS -#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE #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(__cpp_deduction_guides) || __cpp_deduction_guides < 201611 -#define _LIBCPP_HAS_NO_DEDUCTION_GUIDES -#endif +#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 !__has_keyword(__is_aggregate) && (_GNUC_VER_NEW < 7001) -#define _LIBCPP_HAS_NO_IS_AGGREGATE -#endif - -#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L -#define _LIBCPP_HAS_NO_COROUTINES -#endif - -// FIXME: Correct this macro when either (A) a feature test macro for the -// spaceship operator is provided, or (B) a compiler provides a complete -// implementation. -#define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR - -// Decide whether to use availability macros. -#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ - !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ - __has_feature(attribute_availability_with_strict) && \ - __has_feature(attribute_availability_in_templates) && \ - __has_extension(pragma_clang_attribute_external_declaration) -# ifdef __APPLE__ -# define _LIBCPP_USE_AVAILABILITY_APPLE -# endif -#endif - -// Define availability macros. -#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,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_BAD_OPTIONAL_ACCESS \ - __attribute__((availability(macosx,strict,introduced=10.14))) \ - __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(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(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ - __attribute__((availability(ios,strict,introduced=6.0))) -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ - __attribute__((availability(macosx,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(ios,strict,introduced=7.0))) -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -# define _LIBCPP_AVAILABILITY_FILESYSTEM \ - __attribute__((availability(macosx,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(watchos,strict,introduced=6.0))), apply_to=any(function,record))") -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") -#else -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX -# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE -# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR -# define _LIBCPP_AVAILABILITY_FILESYSTEM -# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP -#endif - -// Define availability that depends on _LIBCPP_NO_EXCEPTIONS. -#ifdef _LIBCPP_NO_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_FUTURE -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS -#else -# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS -#endif - -// The stream API was dropped and re-added in the dylib shipped on macOS -// and iOS. We can only assume the dylib to provide these definitions for -// macosx >= 10.9 and ios >= 7.0. Otherwise, the definitions are available -// from the headers, but not from the dylib. Explicit instantiation -// declarations for streams exist conditionally to this; if we provide -// an explicit instantiation declaration and we try to deploy to a dylib -// that does not provide those symbols, we'll get a load-time error. -#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ - ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)) -# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB +#if !defined(__cpp_impl_coroutine) || __cpp_impl_coroutine < 201902L +#define _LIBCPP_HAS_NO_CXX20_COROUTINES #endif #if defined(_LIBCPP_COMPILER_IBM) @@ -1457,7 +1383,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #ifndef _LIBCPP_NO_AUTO_LINK # if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) -# if defined(_DLL) +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) # pragma comment(lib, "c++.lib") # else # pragma comment(lib, "libc++.lib") @@ -1465,8 +1391,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) #endif // _LIBCPP_NO_AUTO_LINK -#define _LIBCPP_UNUSED_VAR(x) ((void)(x)) - // 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. // @@ -1478,6 +1402,34 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # 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 __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 + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/include/__config_site.in b/include/__config_site.in index 1ccc158c6..59ca22981 100644 --- a/include/__config_site.in +++ b/include/__config_site.in @@ -14,23 +14,27 @@ #cmakedefine _LIBCPP_ABI_FORCE_ITANIUM #cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT #cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT -#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE -#cmakedefine _LIBCPP_HAS_NO_STDIN -#cmakedefine _LIBCPP_HAS_NO_STDOUT #cmakedefine _LIBCPP_HAS_NO_THREADS #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK -#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #cmakedefine _LIBCPP_HAS_MUSL_LIBC #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL #cmakedefine _LIBCPP_HAS_THREAD_API_WIN32 #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS +#cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME -#cmakedefine01 _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT +#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@ #cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ +#cmakedefine _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY #cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS +#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE +#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION +#cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS +#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FORMAT +#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_RANGES @_LIBCPP_ABI_DEFINES@ +@_LIBCPP_EXTRA_SITE_DEFINES@ #endif // _LIBCPP_CONFIG_SITE diff --git a/include/__coroutine/coroutine_handle.h b/include/__coroutine/coroutine_handle.h new file mode 100644 index 000000000..64657c058 --- /dev/null +++ b/include/__coroutine/coroutine_handle.h @@ -0,0 +1,202 @@ +//===----------------------------------------------------------------------===// +// +// 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___COROUTINE_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H + +#include <__config> +#include <__debug> +#include <__functional/hash.h> +#include <__memory/addressof.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.handle] +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle; + +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + + void* __handle_ = nullptr; +}; + +// [coroutine.handle.compare] +inline _LIBCPP_HIDE_FROM_ABI +constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return __x.address() == __y.address(); +} +inline _LIBCPP_HIDE_FROM_ABI +constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return compare_three_way()(__x.address(), __y.address()); +} + +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + static coroutine_handle from_promise(_Promise& __promise) { + using _RawPromise = typename remove_cv<_Promise>::type; + coroutine_handle __tmp; + __tmp.__handle_ = + __builtin_coro_promise(_VSTD::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + + // [coroutine.handle.promise], promise access + _LIBCPP_HIDE_FROM_ABI + _Promise& promise() const { + return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + void* __handle_ = nullptr; +}; + +// [coroutine.handle.hash] +template +struct hash> { + _LIBCPP_HIDE_FROM_ABI + size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash()(__v.address()); } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H diff --git a/include/__coroutine/coroutine_traits.h b/include/__coroutine/coroutine_traits.h new file mode 100644 index 000000000..bfa69552b --- /dev/null +++ b/include/__coroutine/coroutine_traits.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___COROUTINE_COROUTINE_TRAITS_H +#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.traits] +// [coroutine.traits.primary] +// The header defined the primary template coroutine_traits such that +// if ArgTypes is a parameter pack of types and if the qualified-id R::promise_type +// is valid and denotes a type ([temp.deduct]), then coroutine_traits +// has the following publicly accessible memebr: +// +// using promise_type = typename R::promise_type; +// +// Otherwise, coroutine_traits has no members. +template +struct __coroutine_traits_sfinae {}; + +template +struct __coroutine_traits_sfinae< + _Tp, typename __void_t::type> +{ + using promise_type = typename _Tp::promise_type; +}; + +template +struct coroutine_traits + : public __coroutine_traits_sfinae<_Ret> +{ +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H diff --git a/include/__coroutine/noop_coroutine_handle.h b/include/__coroutine/noop_coroutine_handle.h new file mode 100644 index 000000000..a29e202f4 --- /dev/null +++ b/include/__coroutine/noop_coroutine_handle.h @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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___COROUTINE_NOOP_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +// [coroutine.noop] +// [coroutine.promise.noop] +struct noop_coroutine_promise {}; + +// [coroutine.handle.noop] +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.noop.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.noop.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr bool done() const noexcept { return false; } + + // [coroutine.handle.noop.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void destroy() const noexcept {} + + // [coroutine.handle.noop.promise], promise access + _LIBCPP_HIDE_FROM_ABI + noop_coroutine_promise& promise() const noexcept { + return *static_cast( + __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); + } + + // [coroutine.handle.noop.address], address + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + +private: + _LIBCPP_HIDE_FROM_ABI + friend coroutine_handle noop_coroutine() noexcept; + +#if __has_builtin(__builtin_coro_noop) + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { + this->__handle_ = __builtin_coro_noop(); + } + + void* __handle_ = nullptr; + +#elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() { } + + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; + + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + + void* __handle_ = &__noop_coroutine_frame_; + + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + +#endif // __has_builtin(__builtin_coro_noop) +}; + +using noop_coroutine_handle = coroutine_handle; + +#if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ + noop_coroutine_handle::__noop_coroutine_frame_{}; +#endif + +// [coroutine.noop.coroutine] +inline _LIBCPP_HIDE_FROM_ABI +noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } + +#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H diff --git a/include/__coroutine/trivial_awaitables.h b/include/__coroutine/trivial_awaitables.h new file mode 100644 index 000000000..c434f83b7 --- /dev/null +++ b/include/__coroutine/trivial_awaitables.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___COROUTINE_TRIVIAL_AWAITABLES_H +#define __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.trivial.awaitables] +struct suspend_never { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +struct suspend_always { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return false; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES) + +#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H diff --git a/include/__debug b/include/__debug index 524c5ff02..a1e21a703 100644 --- a/include/__debug +++ b/include/__debug @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- __debug ----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,6 +12,7 @@ #include <__config> #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -22,31 +23,26 @@ #endif #if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) -# include -# include # include +# include +# include #endif -#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) -# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : \ - _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) -#endif - -#if _LIBCPP_DEBUG_LEVEL >= 2 -#ifndef _LIBCPP_DEBUG_ASSERT -#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) -#endif -#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ -#endif - -#ifndef _LIBCPP_ASSERT -# define _LIBCPP_ASSERT(x, m) ((void)0) -#endif -#ifndef _LIBCPP_DEBUG_ASSERT +#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))) +#else +# error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2 #endif -#ifndef _LIBCPP_DEBUG_MODE -#define _LIBCPP_DEBUG_MODE(...) ((void)0) + +#if !defined(_LIBCPP_ASSERT) +# define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m) #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -59,7 +55,7 @@ struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { __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 std::string what() const; + _LIBCPP_FUNC_VIS string what() const; const char* __file_; int __line_; @@ -83,7 +79,7 @@ void __libcpp_abort_debug_function(__libcpp_debug_info const&); _LIBCPP_FUNC_VIS bool __libcpp_set_debug_function(__libcpp_debug_function_type __func); -#if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) +#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) struct _LIBCPP_TYPE_VIS __c_node; @@ -226,7 +222,7 @@ public: template _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { - return ::new(__mem) _C_node<_Cont>(__c, __next); + return ::new (__mem) _C_node<_Cont>(__c, __next); } template @@ -271,9 +267,28 @@ _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); -#endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) +#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_c(_Tp* __c) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_c(__c); +#else + (void)(__c); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_i(_Tp* __i) { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_i(__i); +#else + (void)(__i); +#endif +} _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP_DEBUG_H - +#endif // _LIBCPP_DEBUG_H diff --git a/include/__errc b/include/__errc index a8ad29f36..68d5fa320 100644 --- a/include/__errc +++ b/include/__errc @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------------- __errc ----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -214,4 +214,4 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ERRC +#endif // _LIBCPP___ERRC diff --git a/include/__filesystem/copy_options.h b/include/__filesystem/copy_options.h new file mode 100644 index 000000000..c0140d457 --- /dev/null +++ b/include/__filesystem/copy_options.h @@ -0,0 +1,80 @@ +// -*- 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___FILESYSTEM_COPY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_COPY_OPTIONS_H + +#include <__availability> +#include <__config> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator~(copy_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_COPY_OPTIONS_H diff --git a/include/__filesystem/directory_entry.h b/include/__filesystem/directory_entry.h new file mode 100644 index 000000000..95e45c023 --- /dev/null +++ b/include/__filesystem/directory_entry.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___FILESYSTEM_DIRECTORY_ENTRY_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H + +#include <__availability> +#include <__config> +#include <__errc> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/filesystem_error.h> +#include <__filesystem/operations.h> +#include <__filesystem/path.h> +#include <__filesystem/perms.h> +#include +#include +#include +#include +#include + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + + +class directory_entry { + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() noexcept = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) { + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { + __refresh(&__ec); + } + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p, error_code& __ec) { + __p_ = __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_.replace_filename(__p); + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p, error_code& __ec) { + __p_ = __p_.parent_path() / __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void refresh() { __refresh(); } + + _LIBCPP_INLINE_VISIBILITY + void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool exists(error_code& __ec) const noexcept { + return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file() const { return __get_ft() == file_type::block; } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::block; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file() const { return __get_ft() == file_type::character; } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::character; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory() const { return __get_ft() == file_type::directory; } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::directory; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo() const { return __get_ft() == file_type::fifo; } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::fifo; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool is_other(error_code& __ec) const noexcept { + return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file() const { return __get_ft() == file_type::regular; } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::regular; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket() const { return __get_ft() == file_type::socket; } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::socket; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink(error_code& __ec) const noexcept { + return __get_sym_ft(&__ec) == file_type::symlink; + } + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size() const { return __get_size(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size(error_code& __ec) const noexcept { + return __get_size(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count() const { return __get_nlink(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count(error_code& __ec) const noexcept { + return __get_nlink(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time() const { return __get_write_time(); } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time(error_code& __ec) const noexcept { + return __get_write_time(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { return __get_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const noexcept { + return __get_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { return __get_symlink_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const noexcept { + return __get_symlink_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<(directory_entry const& __rhs) const noexcept { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const noexcept { + return __p_ == __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const noexcept { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const noexcept { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>(directory_entry const& __rhs) const noexcept { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const noexcept { + return __p_ >= __rhs.__p_; + } + + template + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + friend class _LIBCPP_HIDDEN __dir_stream; + + enum _CacheType : unsigned char { + _Empty, + _IterSymlink, + _IterNonSymlink, + _RefreshSymlink, + _RefreshSymlinkUnresolved, + _RefreshNonSymlink + }; + + struct __cached_data { + uintmax_t __size_; + uintmax_t __nlink_; + file_time_type __write_time_; + perms __sym_perms_; + perms __non_sym_perms_; + file_type __type_; + _CacheType __cache_type_; + + _LIBCPP_INLINE_VISIBILITY + __cached_data() noexcept { __reset(); } + + _LIBCPP_INLINE_VISIBILITY + void __reset() { + __cache_type_ = _Empty; + __type_ = file_type::none; + __sym_perms_ = __non_sym_perms_ = perms::unknown; + __size_ = __nlink_ = uintmax_t(-1); + __write_time_ = file_time_type::min(); + } + }; + + _LIBCPP_INLINE_VISIBILITY + static __cached_data __create_iter_result(file_type __ft) { + __cached_data __data; + __data.__type_ = __ft; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); + return __data; + } + + _LIBCPP_INLINE_VISIBILITY + void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = _VSTD::move(__p); + __data_ = __dt; + } + + _LIBCPP_FUNC_VIS + error_code __do_refresh() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_dne_error(error_code const& __ec) { + if (!__ec) + return true; + switch (static_cast(__ec.value())) { + case errc::no_such_file_or_directory: + case errc::not_a_directory: + return true; + default: + return false; + } + } + + _LIBCPP_INLINE_VISIBILITY + void __handle_error(const char* __msg, error_code* __dest_ec, + error_code const& __ec, bool __allow_dne = false) const { + if (__dest_ec) { + *__dest_ec = __ec; + return; + } + if (__ec && (!__allow_dne || !__is_dne_error(__ec))) + __throw_filesystem_error(__msg, __p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + /*allow_dne*/ true); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_sym_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + return __symlink_status(__p_, __ec).type(); + case _IterSymlink: + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + if (__ec) + __ec->clear(); + return file_type::symlink; + case _IterNonSymlink: + case _RefreshNonSymlink: + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec).type(); + case _IterNonSymlink: + case _RefreshNonSymlink: + case _RefreshSymlink: { + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec); + case _RefreshNonSymlink: + case _RefreshSymlink: + return file_status(__get_ft(__ec), __data_.__non_sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_symlink_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + return __symlink_status(__p_, __ec); + case _RefreshNonSymlink: + return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_size(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__file_size(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::file_size", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { + errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory + : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, + make_error_code(__err_kind)); + } + return __data_.__size_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_nlink(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__hard_link_count(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + (void)__get_ft(&__m_ec); + __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); + return __data_.__nlink_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type __get_write_time(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__last_write_time(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::last_write_time", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && + __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, + make_error_code(errc::value_too_large)); + return __data_.__write_time_; + } + } + _LIBCPP_UNREACHABLE(); + } + +private: + _Path __p_; + __cached_data __data_; +}; + +class __dir_element_proxy { +public: + inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { + return _VSTD::move(__elem_); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) + : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H diff --git a/include/__filesystem/directory_iterator.h b/include/__filesystem/directory_iterator.h new file mode 100644 index 000000000..cfaf2064b --- /dev/null +++ b/include/__filesystem/directory_iterator.h @@ -0,0 +1,150 @@ +// -*- 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___FILESYSTEM_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H + +#include <__availability> +#include <__config> +#include <__debug> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_HIDDEN __dir_stream; +class directory_iterator { +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + directory_iterator() noexcept {} + + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) {} + + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) {} + + directory_iterator(const path& __p, error_code& __ec) + : directory_iterator(__p, &__ec) {} + + 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; + + directory_iterator& operator=(directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + ~directory_iterator() = default; + + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __dereference(); + } + + const directory_entry* operator->() const { return &**this; } + + directory_iterator& operator++() { return __increment(); } + + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +private: + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code*, + directory_options = directory_options::none); + + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_INLINE_VISIBILITY 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 +begin(directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY directory_iterator +end(directory_iterator) noexcept { + return directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H diff --git a/include/__filesystem/directory_options.h b/include/__filesystem/directory_options.h new file mode 100644 index 000000000..79c0c2cba --- /dev/null +++ b/include/__filesystem/directory_options.h @@ -0,0 +1,78 @@ +// -*- 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___FILESYSTEM_DIRECTORY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H + +#include <__availability> +#include <__config> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator&(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator|(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator^(directory_options _LHS, + directory_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator~(directory_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H diff --git a/include/__filesystem/file_status.h b/include/__filesystem/file_status.h new file mode 100644 index 000000000..a8f653ab4 --- /dev/null +++ b/include/__filesystem/file_status.h @@ -0,0 +1,68 @@ +// -*- 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___FILESYSTEM_FILE_STATUS_H +#define _LIBCPP___FILESYSTEM_FILE_STATUS_H + +#include <__availability> +#include <__config> +#include <__filesystem/file_type.h> +#include <__filesystem/perms.h> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS file_status { +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), + __prms_(__prms) {} + + file_status(const file_status&) noexcept = default; + file_status(file_status&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) noexcept = default; + file_status& operator=(file_status&&) noexcept = default; + + // observers + _LIBCPP_INLINE_VISIBILITY + file_type type() const noexcept { return __ft_; } + + _LIBCPP_INLINE_VISIBILITY + perms permissions() const noexcept { return __prms_; } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void type(file_type __ft) noexcept { __ft_ = __ft; } + + _LIBCPP_INLINE_VISIBILITY + void permissions(perms __p) noexcept { __prms_ = __p; } + +private: + file_type __ft_; + perms __prms_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_STATUS_H diff --git a/include/__filesystem/file_time_type.h b/include/__filesystem/file_time_type.h new file mode 100644 index 000000000..590146a06 --- /dev/null +++ b/include/__filesystem/file_time_type.h @@ -0,0 +1,27 @@ +// -*- 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___FILESYSTEM_FILE_TIME_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H + +#include <__availability> +#include <__config> +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +typedef chrono::time_point<_FilesystemClock> file_time_type; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H diff --git a/include/__filesystem/file_type.h b/include/__filesystem/file_type.h new file mode 100644 index 000000000..93bee86ad --- /dev/null +++ b/include/__filesystem/file_type.h @@ -0,0 +1,39 @@ +// -*- 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___FILESYSTEM_FILE_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TYPE_H + +#include <__availability> +#include <__config> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +// On Windows, the library never identifies files as block, character, fifo +// or socket. +enum class _LIBCPP_ENUM_VIS file_type : signed char { + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TYPE_H diff --git a/include/__filesystem/filesystem_error.h b/include/__filesystem/filesystem_error.h new file mode 100644 index 000000000..0b1874b0e --- /dev/null +++ b/include/__filesystem/filesystem_error.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___FILESYSTEM_FILESYSTEM_ERROR_H +#define _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H + +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include <__memory/shared_ptr.h> +#include +#include +#include +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(path(), path())) { + __create_what(0); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, path())) { + __create_what(1); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, __p2)) { + __create_what(2); + } + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const noexcept { return __storage_->__p1_; } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const noexcept { return __storage_->__p2_; } + + filesystem_error(const filesystem_error&) = default; + ~filesystem_error() override; // key function + + _LIBCPP_INLINE_VISIBILITY + const char* what() const noexcept override { + return __storage_->__what_.c_str(); + } + + void __create_what(int __num_paths); + +private: + struct _LIBCPP_HIDDEN _Storage { + _LIBCPP_INLINE_VISIBILITY + _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + + path __p1_; + path __p2_; + string __what_; + }; + shared_ptr<_Storage> __storage_; +}; + +// TODO(ldionne): We need to pop the pragma and push it again after +// filesystem_error to work around PR41078. +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_NO_EXCEPTIONS +void __throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(_VSTD::forward<_Args>(__args)...); +} +#else +void __throw_filesystem_error(_Args&&...) { + _VSTD::abort(); +} +#endif +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H diff --git a/include/__filesystem/operations.h b/include/__filesystem/operations.h new file mode 100644 index 000000000..918b4f936 --- /dev/null +++ b/include/__filesystem/operations.h @@ -0,0 +1,197 @@ +// -*- 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___FILESYSTEM_OPERATIONS_H +#define _LIBCPP___FILESYSTEM_OPERATIONS_H + +#include <__availability> +#include <__config> +#include <__filesystem/copy_options.h> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/path.h> +#include <__filesystem/perm_options.h> +#include <__filesystem/perms.h> +#include <__filesystem/space_info.h> +#include +#include +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directories(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path& p, const path& attributes, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __last_write_time(const path& p, file_time_type new_time, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __read_symlink(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS bool __remove(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS void __rename(const path& from, const path& to, error_code* ec = nullptr); +_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_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { + auto __s = __status(__p, &__ec); + if (status_known(__s)) + __ec.clear(); + 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)); } +_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); } +_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_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return {}; + path __tmp_base = __weakly_canonical(__base, &__ec); + if (__ec) + return {}; + 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_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return path(); + path __tmpbase = __weakly_canonical(__base, &__ec); + if (__ec) + return path(); + 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); } +_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); } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_OPERATIONS_H diff --git a/include/__filesystem/path.h b/include/__filesystem/path.h new file mode 100644 index 000000000..77547cbac --- /dev/null +++ b/include/__filesystem/path.h @@ -0,0 +1,1018 @@ +// -*- 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___FILESYSTEM_PATH_H +#define _LIBCPP___FILESYSTEM_PATH_H + +#include <__availability> +#include <__config> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include // for quoted +# include +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +struct __can_convert_char { + static const bool value = false; +}; +template +struct __can_convert_char : public __can_convert_char<_Tp> {}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = wchar_t; +}; +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char8_t; +}; +#endif +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char16_t; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char32_t; +}; + +template +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { +#if defined(_LIBCPP_WIN32API) + return __e == _ECharT('/') || __e == _ECharT('\\'); +#else + return __e == _ECharT('/'); +#endif +} + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +typedef u8string __u8_string; +#else +typedef string __u8_string; +#endif + +struct _NullSentinel {}; + +template +using _Void = void; + +template +struct __is_pathable_string : public false_type {}; + +template +struct __is_pathable_string< + basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template +struct __is_pathable_string< + basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template ::type, + class _UnqualPtrType = + typename remove_const::type>::type, + bool _IsCharPtr = is_pointer<_DS>::value&& + __can_convert_char<_UnqualPtrType>::value> +struct __is_pathable_char_array : false_type {}; + +template +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char::type> { + using _Base = __can_convert_char::type>; + + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; + const _ECharT __sentinel = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinel; ++__e) + ; + return __e; + } + + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template ::value, + class = void> +struct __is_pathable_iter : false_type {}; + +template +struct __is_pathable_iter< + _Iter, true, + _Void::value_type>::__char_type> > + : __can_convert_char::value_type> { + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + static _Iter __range_begin(_Iter __b) { return __b; } + static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } + + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template ::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + +template +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { +}; + +template +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + +#if defined(_LIBCPP_WIN32API) +typedef wstring __path_string; +typedef wchar_t __path_value; +#else +typedef string __path_string; +typedef char __path_value; +#endif + +#if defined(_LIBCPP_WIN32API) +_LIBCPP_FUNC_VIS +size_t __wide_to_char(const wstring&, char*, size_t); +_LIBCPP_FUNC_VIS +size_t __char_to_wide(const string&, wchar_t*, size_t); +#endif + +template +struct _PathCVT; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +template +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, + "Char type not convertible"); + + typedef __narrow_to_utf8 _Narrower; +#if defined(_LIBCPP_WIN32API) + typedef __widen_from_utf8 _Widener; +#endif + + static void __append_range(__path_string& __dest, _ECharT const* __b, + _ECharT const* __e) { +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __b, __e); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __b, __e); +#endif + } + + template + static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) + return; + basic_string<_ECharT> __tmp(__b, __e); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinel = _ECharT{}; + if (*__b == __sentinel) + return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + +template <> +struct _PathCVT<__path_value> { + + template + 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) + __dest.push_back(*__b); + } + + template + 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 + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + for (; *__b != __sentinel; ++__b) + __dest.push_back(*__b); + } + + template + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +#if defined(_LIBCPP_WIN32API) +template <> +struct _PathCVT { + + static void + __append_string(__path_string& __dest, const basic_string &__str) { + size_t __size = __char_to_wide(__str, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__pos + __size); + __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); + } + + template + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + basic_string __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); + __append_string(__dest, __tmp); + } + + template + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +template +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + typedef __widen_from_utf8 _Widener; + + template + static void __append(_Str& __dest, const __path_string& __src) { + string __utf8; + _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); + } +}; + +template <> +struct _PathExport { + template + static void __append(_Str& __dest, const __path_string& __src) { + size_t __size = __wide_to_char(__src, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__size); + __wide_to_char(__src, const_cast(__dest.data()) + __pos, __size); + } +}; + +template <> +struct _PathExport { + template + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +template <> +struct _PathExport { + template + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + + template + static void __append(_Str& __dest, const __path_string& __src) { + _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); + } +}; +#endif /* !_LIBCPP_HAS_NO_CHAR8_T */ +#endif /* _LIBCPP_WIN32API */ + +class _LIBCPP_TYPE_VIS path { + template + using _EnableIfPathable = + typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template + using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + +public: +#if defined(_LIBCPP_WIN32API) + typedef wchar_t value_type; + static constexpr value_type preferred_separator = L'\\'; +#else + typedef char value_type; + static constexpr value_type preferred_separator = '/'; +#endif + typedef basic_string string_type; + typedef basic_string_view __string_view; + + enum _LIBCPP_ENUM_VIS format : unsigned char { + auto_format, + native_format, + generic_format + }; + + // 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 + : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_INLINE_VISIBILITY + path(string_type&& __s, format = format::auto_format) noexcept + : __pn_(_VSTD::move(__s)) {} + + template > + path(const _Source& __src, format = format::auto_format) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template + path(_InputIt __first, _InputIt __last, format = format::auto_format) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + +/* +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); +#endif +*/ + + _LIBCPP_INLINE_VISIBILITY + ~path() = default; + + // assignments + _LIBCPP_INLINE_VISIBILITY + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(path&& __p) noexcept { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& assign(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator=(const _Source& __src) { + return this->assign(__src); + } + + template + _EnableIfPathable<_Source> assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +public: + // appends +#if defined(_LIBCPP_WIN32API) + path& operator/=(const path& __p) { + auto __p_root_name = __p.__root_name(); + auto __p_root_name_size = __p_root_name.size(); + if (__p.is_absolute() || + (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { + __pn_ = __p.__pn_; + return *this; + } + if (__p.has_root_directory()) { + path __root_name_str = root_name(); + __pn_ = __root_name_str.native(); + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + if (has_filename() || (!has_root_directory() && is_absolute())) + __pn_ += preferred_separator; + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return operator/=(path(__src)); + } + + template + _EnableIfPathable<_Source> append(const _Source& __src) { + return operator/=(path(__src)); + } + + template + path& append(_InputIt __first, _InputIt __last) { + return operator/=(path(__first, __last)); + } +#else + path& operator/=(const path& __p) { + if (__p.is_absolute()) { + __pn_ = __p.__pn_; + return *this; + } + if (has_filename()) + __pn_ += preferred_separator; + __pn_ += __p.native(); + return *this; + } + + // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src + // is known at compile time to be "/' since the user almost certainly intended + // to append a separator instead of overwriting the path with "/" + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template + _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src)); + if (__source_is_absolute) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_source(__pn_, __src); + return *this; + } + + template + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last && __is_separator(*__first)) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_range(__pn_, __first, __last); + return *this; + } +#endif + + // concatenation + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + template + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) { + _PathCVT<_ECharT>::__append_source(__pn_, + basic_string_view<_ECharT>(&__x, 1)); + return *this; + } + + template + _EnableIfPathable<_Source> operator+=(const _Source& __x) { + return this->concat(__x); + } + + template + _EnableIfPathable<_Source> concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() noexcept { __pn_.clear(); } + + path& make_preferred() { +#if defined(_LIBCPP_WIN32API) + _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); +#endif + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& remove_filename() { + auto __fname = __filename(); + if (!__fname.empty()) + __pn_.erase(__fname.data() - __pn_.data()); + return *this; + } + + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + _LIBCPP_INLINE_VISIBILITY + void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + + // private helper to allow reserving memory in the path + _LIBCPP_INLINE_VISIBILITY + void __reserve(size_t __s) { __pn_.reserve(__s); } + + // native format observers + _LIBCPP_INLINE_VISIBILITY + const string_type& native() const noexcept { return __pn_; } + + _LIBCPP_INLINE_VISIBILITY + const value_type* c_str() const noexcept { return __pn_.c_str(); } + + _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } + +#if defined(_LIBCPP_WIN32API) + _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; } + + _VSTD::wstring generic_wstring() const { + _VSTD::wstring __s; + __s.resize(__pn_.size()); + _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); + return __s; + } + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _PathExport<_ECharT>::__append(__s, __pn_); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { + return string(); + } + _LIBCPP_INLINE_VISIBILITY __u8_string u8string() const { + using _CVT = __narrow_to_utf8; + __u8_string __s; + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { + return string(); + } + + // generic format observers + template , + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s = string<_ECharT, _Traits, _Allocator>(__a); + // Note: This (and generic_u8string below) is slightly suboptimal as + // it iterates twice over the string; once to convert it to the right + // character type, and once to replace path delimiters. + _VSTD::replace(__s.begin(), __s.end(), + static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); + return __s; + } + + _VSTD::string generic_string() const { return generic_string(); } + _VSTD::u16string generic_u16string() const { return generic_string(); } + _VSTD::u32string generic_u32string() const { return generic_string(); } + __u8_string generic_u8string() const { + __u8_string __s = u8string(); + _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); + return __s; + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#else /* _LIBCPP_WIN32API */ + + _LIBCPP_INLINE_VISIBILITY _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()); } +#else + _LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { + return string(); + } +#endif + _LIBCPP_INLINE_VISIBILITY _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_INLINE_VISIBILITY _VSTD::u32string u32string() const { + return string(); + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ + + // generic format observers + _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()); } +#else + _VSTD::string generic_u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + 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(); } +#endif + _VSTD::u16string generic_u16string() const { return string(); } + _VSTD::u32string generic_u32string() const { return string(); } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#endif /* !_LIBCPP_WIN32API */ + +private: + int __compare(__string_view) const; + __string_view __root_name() const; + __string_view __root_directory() const; + __string_view __root_path_raw() const; + __string_view __relative_path() const; + __string_view __parent_path() const; + __string_view __filename() const; + __string_view __stem() const; + __string_view __extension() const; + +public: + // compare + _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept { + return __compare(__p.__pn_); + } + _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { + return __compare(__s); + } + + // decomposition + _LIBCPP_INLINE_VISIBILITY path root_name() const { + return string_type(__root_name()); + } + _LIBCPP_INLINE_VISIBILITY path root_directory() const { + return string_type(__root_directory()); + } + _LIBCPP_INLINE_VISIBILITY 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 { + return string_type(__relative_path()); + } + _LIBCPP_INLINE_VISIBILITY path parent_path() const { + return string_type(__parent_path()); + } + _LIBCPP_INLINE_VISIBILITY path filename() const { + return string_type(__filename()); + } + _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); } + _LIBCPP_INLINE_VISIBILITY path extension() const { + return string_type(__extension()); + } + + // query + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool + empty() const noexcept { + return __pn_.empty(); + } + + _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { + return !__root_name().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { + return !__root_directory().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { + return !__root_path_raw().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { + return !__relative_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { + return !__parent_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_filename() const { + return !__filename().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_extension() const { + return !__extension().empty(); + } + + _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { +#if defined(_LIBCPP_WIN32API) + __string_view __root_name_str = __root_name(); + __string_view __root_dir = __root_directory(); + if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { + // A drive letter with no root directory is relative, e.g. x:example. + return !__root_dir.empty(); + } + // If no root name, it's relative, e.g. \example is relative to the current drive + if (__root_name_str.empty()) + return false; + if (__root_name_str.size() < 3) + return false; + // A server root name, like \\server, is always absolute + if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') + return false; + if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') + return false; + // Seems to be a server root name + return true; +#else + return has_root_directory(); +#endif + } + _LIBCPP_INLINE_VISIBILITY 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 { + path __result = this->lexically_relative(__base); + if (__result.native().empty()) + return *this; + return __result; + } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if::value && + is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.native()); + return __os; + } + + template + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if::value || + !is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); + return __os; + } + + template + _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { + basic_string<_CharT, _Traits> __tmp; + __is >> __quoted(__tmp); + __p = __tmp; + return __is; + } +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + + friend _LIBCPP_INLINE_VISIBILITY 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 { + return __lhs.__compare(__rhs.__pn_) != 0; + } + friend _LIBCPP_INLINE_VISIBILITY 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 { + return __lhs.__compare(__rhs.__pn_) <= 0; + } + friend _LIBCPP_INLINE_VISIBILITY 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 { + return __lhs.__compare(__rhs.__pn_) >= 0; + } + + friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, + const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } +private: + inline _LIBCPP_INLINE_VISIBILITY path& + __assign_view(__string_view const& __s) noexcept { + __pn_ = string_type(__s); + return *this; + } + string_type __pn_; +}; + +inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) noexcept; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_H diff --git a/include/__filesystem/path_iterator.h b/include/__filesystem/path_iterator.h new file mode 100644 index 000000000..08039e4c8 --- /dev/null +++ b/include/__filesystem/path_iterator.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___FILESYSTEM_PATH_ITERATOR_H +#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H + +#include <__availability> +#include <__config> +#include <__debug> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS path::iterator { +public: + enum _ParserState : unsigned char { + _Singular, + _BeforeBegin, + _InRootName, + _InRootDir, + _InFilenames, + _InTrailingSep, + _AtEnd + }; + +public: + typedef input_iterator_tag iterator_category; + typedef bidirectional_iterator_tag iterator_concept; + + typedef path value_type; + typedef ptrdiff_t difference_type; + typedef const path* pointer; + typedef path reference; + +public: + _LIBCPP_INLINE_VISIBILITY + iterator() + : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), + __state_(_Singular) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { return __stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { return &__stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != _AtEnd, + "attempting to increment the end iterator"); + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, + const iterator&); + + iterator& __increment(); + iterator& __decrement(); + + path __stashed_elem_; + const path* __path_ptr_; + path::__string_view __entry_; + _ParserState __state_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, + const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__entry_.data() == __rhs.__entry_.data(); +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, + const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H diff --git a/include/__filesystem/perm_options.h b/include/__filesystem/perm_options.h new file mode 100644 index 000000000..62cd8f575 --- /dev/null +++ b/include/__filesystem/perm_options.h @@ -0,0 +1,73 @@ +// -*- 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___FILESYSTEM_PERM_OPTIONS_H +#define _LIBCPP___FILESYSTEM_PERM_OPTIONS_H + +#include <__availability> +#include <__config> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { + replace = 1, + add = 2, + remove = 4, + nofollow = 8 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator&(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator|(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator^(perm_options _LHS, perm_options _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator~(perm_options _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERM_OPTIONS_H diff --git a/include/__filesystem/perms.h b/include/__filesystem/perms.h new file mode 100644 index 000000000..832f8b07e --- /dev/null +++ b/include/__filesystem/perms.h @@ -0,0 +1,91 @@ +// -*- 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___FILESYSTEM_PERMS_H +#define _LIBCPP___FILESYSTEM_PERMS_H + +#include <__availability> +#include <__config> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +// On Windows, these permission bits map to one single readonly flag per +// file, and the executable bit is always returned as set. When setting +// permissions, as long as the write bit is set for either owner, group or +// others, the readonly flag is cleared. +enum class _LIBCPP_ENUM_VIS perms : unsigned { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator&(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) & + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator|(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) | + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator^(perms _LHS, perms _RHS) { + return static_cast(static_cast(_LHS) ^ + static_cast(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator~(perms _LHS) { + return static_cast(~static_cast(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERMS_H diff --git a/include/__filesystem/recursive_directory_iterator.h b/include/__filesystem/recursive_directory_iterator.h new file mode 100644 index 000000000..b80d59750 --- /dev/null +++ b/include/__filesystem/recursive_directory_iterator.h @@ -0,0 +1,181 @@ +// -*- 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___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H + +#include <__availability> +#include <__config> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; + using iterator_category = input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() noexcept : __rec_(false) {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator( + const path& __p, directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, directory_options __xoptions, + error_code& __ec) + : recursive_directory_iterator(__p, __xoptions, &__ec) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) + : recursive_directory_iterator(__p, directory_options::none, &__ec) {} + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator& + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const { return __dereference(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const { return &__dereference(); } + + recursive_directory_iterator& operator++() { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) { + return __increment(&__ec); + } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() { __rec_ = false; } + +private: + _LIBCPP_FUNC_VIS + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code* __ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec = nullptr); + + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) noexcept; + + struct _LIBCPP_HIDDEN __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +begin(recursive_directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +end(recursive_directory_iterator) noexcept { + return recursive_directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H diff --git a/include/__filesystem/space_info.h b/include/__filesystem/space_info.h new file mode 100644 index 000000000..098f08567 --- /dev/null +++ b/include/__filesystem/space_info.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___FILESYSTEM_SPACE_INFO_H +#define _LIBCPP___FILESYSTEM_SPACE_INFO_H + +#include <__availability> +#include <__config> +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +struct _LIBCPP_TYPE_VIS space_info { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_SPACE_INFO_H diff --git a/include/__filesystem/u8path.h b/include/__filesystem/u8path.h new file mode 100644 index 000000000..dca3b0c50 --- /dev/null +++ b/include/__filesystem/u8path.h @@ -0,0 +1,96 @@ +// -*- 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___FILESYSTEM_U8PATH_H +#define _LIBCPP___FILESYSTEM_U8PATH_H + +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _InputIt __l) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + string __tmp(__f, __l); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +#else + return path(__f, __l); +#endif /* !_LIBCPP_WIN32API */ +} + +#if defined(_LIBCPP_WIN32API) +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _NullSentinel) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); + string __tmp; + const char __sentinel = char{}; + for (; *__f != __sentinel; ++__f) + __tmp.push_back(*__f); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +} +#endif /* _LIBCPP_WIN32API */ + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_Source>::value, path>::type + u8path(const _Source& __s) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type " + "'char' or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + using _Traits = __is_pathable<_Source>; + return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); +#else + return path(__s); +#endif +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_U8PATH_H diff --git a/include/__format/format_arg.h b/include/__format/format_arg.h new file mode 100644 index 000000000..e76b0dd50 --- /dev/null +++ b/include/__format/format_arg.h @@ -0,0 +1,292 @@ +// -*- 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_H +#define _LIBCPP___FORMAT_FORMAT_ARG_H + +#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 <__memory/addressof.h> +#include <__variant/monostate.h> +#include +#include + +#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 + +// 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. +enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { + __none, + __boolean, + __char_type, + __int, + __long_long, + __i128, + __unsigned, + __unsigned_long_long, + __u128, + __float, + __double, + __long_double, + __const_char_type_ptr, + __string_view, + __ptr, + __handle +}; +} // namespace __format + +template +_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{}); + case __format::__arg_t::__boolean: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__boolean); + case __format::__arg_t::__char_type: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__char_type); + case __format::__arg_t::__int: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__int); + case __format::__arg_t::__long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__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 + case __format::__arg_t::__unsigned: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__unsigned); + case __format::__arg_t::__unsigned_long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), + __arg.__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 + case __format::__arg_t::__float: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__float); + case __format::__arg_t::__double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__double); + case __format::__arg_t::__long_double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__long_double); + case __format::__arg_t::__const_char_type_ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), + __arg.__const_char_type_ptr); + case __format::__arg_t::__string_view: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__string_view); + case __format::__arg_t::__ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__ptr); + case __format::__arg_t::__handle: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__handle); + } + _LIBCPP_UNREACHABLE(); +} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { +public: + class _LIBCPP_TEMPLATE_VIS handle; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept + : __type_{__format::__arg_t::__none} {} + + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { + return __type_ != __format::__arg_t::__none; + } + +private: + using char_type = typename _Context::char_type; + + // TODO FMT Implement constrain [format.arg]/4 + // Constraints: The template specialization + // typename Context::template formatter_type + // meets the Formatter requirements ([formatter.requirements]). The extent + // to which an implementation determines that the specialization meets the + // Formatter requirements is unspecified, except that as a minimum the + // expression + // typename Context::template formatter_type() + // .format(declval(), declval()) + // shall be well-formed when treated as an unevaluated operand. + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT friend __format_arg_store<_Ctx, _Args...> + make_format_args(const _Args&...); + + template + _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 __string_view; + const void* __ptr; + handle __handle; + }; + __format::__arg_t __type_; + + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(bool __v) noexcept + : __boolean(__v), __type_(__format::__arg_t::__boolean) {} + + template + _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(__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(__v); + __type_ = __format::__arg_t::__int; + } else if constexpr (sizeof(_Tp) <= sizeof(long long)) { + __long_long = static_cast(__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(__v); + __type_ = __format::__arg_t::__unsigned; + } else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) { + __unsigned_long_long = static_cast(__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 + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg( + basic_string_view __s) noexcept + : __string_view{__s.data(), __s.size()}, + __type_(__format::__arg_t::__string_view) {} + + template + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg( + const basic_string& __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 + requires is_void_v<_Tp> _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(_Tp* __p) noexcept + : __ptr(__p), __type_(__format::__arg_t::__ptr) {} + + template + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(const _Tp& __v) noexcept + : __handle(__v), __type_(__format::__arg_t::__handle) {} +}; + +template +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& __parse_ctx, _Context& __ctx) const { + __format_(__parse_ctx, __ctx, __ptr_); + } + +private: + const void* __ptr_; + void (*__format_)(basic_format_parse_context&, _Context&, const void*); + + template + _LIBCPP_HIDE_FROM_ABI explicit handle(const _Tp& __v) noexcept + : __ptr_(_VSTD::addressof(__v)), + __format_([](basic_format_parse_context& __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(__ptr), __ctx)); + }) {} +}; + +#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/include/__format/format_args.h b/include/__format/format_args.h new file mode 100644 index 000000000..0a26b95d1 --- /dev/null +++ b/include/__format/format_args.h @@ -0,0 +1,71 @@ +// -*- 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_ARGS_H +#define _LIBCPP___FORMAT_FORMAT_ARGS_H + +#include <__availability> +#include <__config> +#include <__format/format_fwd.h> +#include + +#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 + +// 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 _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 + _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_arg<_Context> get(size_t __id) const noexcept { + return __id < __size_ ? __data_[__id] : basic_format_arg<_Context>{}; + } + + _LIBCPP_HIDE_FROM_ABI size_t __size() const noexcept { return __size_; } + +private: + size_t __size_{0}; + const basic_format_arg<_Context>* __data_{nullptr}; +}; + +#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/include/__format/format_context.h b/include/__format/format_context.h new file mode 100644 index 000000000..570bf7e90 --- /dev/null +++ b/include/__format/format_context.h @@ -0,0 +1,165 @@ +// -*- 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_CONTEXT_H +#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H + +#include <__availability> +#include <__config> +#include <__format/format_args.h> +#include <__format/format_fwd.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/concepts.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#include +#endif + +#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 + +// 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 +requires output_iterator<_OutIt, const _CharT&> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +/** + * Helper to create a basic_format_context. + * + * This is needed since the constructor is private. + */ +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args, + optional<_VSTD::locale>&& __loc = nullopt) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, + _VSTD::move(__loc)); +} +#else +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); +} +#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, vector, or any other container with contiguous +// storage by wrapping those in temporary objects with a uniform interface +// (such as a span) and polymorphic reallocation. - end note] + +using format_context = basic_format_context, char>; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_context = basic_format_context, wchar_t>; +#endif + +template +requires output_iterator<_OutIt, const _CharT&> +class + // clang-format off + _LIBCPP_TEMPLATE_VIS + _LIBCPP_AVAILABILITY_FORMAT + _LIBCPP_PREFERRED_NAME(format_context) + _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) + // clang-format on + basic_format_context { +public: + using iterator = _OutIt; + using char_type = _CharT; + template + using formatter_type = formatter<_Tp, _CharT>; + + basic_format_context(const basic_format_context&) = delete; + basic_format_context& operator=(const basic_format_context&) = delete; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg + arg(size_t __id) const { + return __args_.get(__id); + } +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { + if (!__loc_) + __loc_ = _VSTD::locale{}; + return *__loc_; + } +#endif + _LIBCPP_HIDE_FROM_ABI iterator out() { return __out_it_; } + _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = __it; } + +private: + iterator __out_it_; + basic_format_args __args_; +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + + // The Standard doesn't specify how the locale is stored. + // [format.context]/6 + // std::locale locale(); + // Returns: The locale passed to the formatting function if the latter + // takes one, and std::locale() otherwise. + // This is done by storing the locale of the constructor in this optional. If + // locale() is called and the optional has no value the value will be created. + // This allows the implementation to lazily create the locale. + // TODO FMT Validate whether lazy creation is the best solution. + optional<_VSTD::locale> __loc_; + + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>, + optional<_VSTD::locale>&&); + + // Note: the Standard doesn't specify the required constructors. + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args, + optional<_VSTD::locale>&& __loc) + : __out_it_(_VSTD::move(__out_it)), __args_(__args), + __loc_(_VSTD::move(__loc)) {} +#else + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>); + + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args) + : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} +#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/include/__format/format_error.h b/include/__format/format_error.h new file mode 100644 index 000000000..ac1d70803 --- /dev/null +++ b/include/__format/format_error.h @@ -0,0 +1,51 @@ +// -*- 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_ERROR_H +#define _LIBCPP___FORMAT_FORMAT_ERROR_H + +#include <__config> +#include + +#ifdef _LIBCPP_NO_EXCEPTIONS +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { +public: + _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) + : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) + : runtime_error(__s) {} + virtual ~format_error() noexcept; +}; + +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void +__throw_format_error(const char* __s) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw format_error(__s); +#else + (void)__s; + _VSTD::abort(); +#endif +} + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ERROR_H diff --git a/include/__format/format_fwd.h b/include/__format/format_fwd.h new file mode 100644 index 000000000..7da30aec5 --- /dev/null +++ b/include/__format/format_fwd.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___FORMAT_FORMAT_FWD_H +#define _LIBCPP___FORMAT_FORMAT_FWD_H + +#include <__availability> +#include <__config> +#include <__iterator/concepts.h> +#include <__utility/forward.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 + +// 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 _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg; + +template +struct _LIBCPP_TEMPLATE_VIS __format_arg_store; + +template +_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Ctx, _Args...> +make_format_args(const _Args&...); + +template +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/include/__format/format_parse_context.h b/include/__format/format_parse_context.h new file mode 100644 index 000000000..289cab9f0 --- /dev/null +++ b/include/__format/format_parse_context.h @@ -0,0 +1,109 @@ +// -*- 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_PARSE_CONTEXT_H +#define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H + +#include <__config> +#include <__format/format_error.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context { +public: + using char_type = _CharT; + using const_iterator = typename basic_string_view<_CharT>::const_iterator; + using iterator = const_iterator; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt, + size_t __num_args = 0) noexcept + : __begin_(__fmt.begin()), + __end_(__fmt.end()), + __indexing_(__unknown), + __next_arg_id_(0), + __num_args_(__num_args) {} + + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& + operator=(const basic_format_parse_context&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { + return __begin_; + } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { + return __end_; + } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { + __begin_ = __it; + } + + _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { + if (__indexing_ == __manual) + __throw_format_error("Using automatic argument numbering in manual " + "argument numbering mode"); + + if (__indexing_ == __unknown) + __indexing_ = __automatic; + return __next_arg_id_++; + } + _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) { + if (__indexing_ == __automatic) + __throw_format_error("Using manual argument numbering in automatic " + "argument numbering mode"); + + if (__indexing_ == __unknown) + __indexing_ = __manual; + + // Throws an exception to make the expression a non core constant + // expression as required by: + // [format.parse.ctx]/11 + // Remarks: Call expressions where id >= num_args_ are not core constant + // expressions ([expr.const]). + // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the + // behavior when id >= num_args_. + if (is_constant_evaluated() && __id >= __num_args_) + __throw_format_error("Argument index outside the valid range"); + } + +private: + iterator __begin_; + iterator __end_; + enum _Indexing { __unknown, __manual, __automatic }; + _Indexing __indexing_; + size_t __next_arg_id_; + size_t __num_args_; +}; + +using format_parse_context = basic_format_parse_context; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_parse_context = basic_format_parse_context; +#endif + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H diff --git a/include/__format/format_string.h b/include/__format/format_string.h new file mode 100644 index 000000000..885e572fc --- /dev/null +++ b/include/__format/format_string.h @@ -0,0 +1,169 @@ +// -*- 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_STRING_H +#define _LIBCPP___FORMAT_FORMAT_STRING_H + +#include <__config> +#include <__debug> +#include <__format/format_error.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 +struct _LIBCPP_TEMPLATE_VIS __parse_number_result { + const _CharT* __ptr; + uint32_t __value; +}; + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end); + +/** + * The maximum value of a numeric argument. + * + * This is used for: + * * arg-id + * * width as value or arg-id. + * * precision as value or arg-id. + * + * The value is compatible with the maximum formatting width and precision + * using the `%*` syntax on a 32-bit system. + */ +inline constexpr uint32_t __number_max = INT32_MAX; + +namespace __detail { +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + __parse_ctx.check_arg_id(0); + return {++__begin, 0}; // can never be larger than the maximum. +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + size_t __value = __parse_ctx.next_arg_id(); + _LIBCPP_ASSERT(__value <= __number_max, + "Compilers don't support this number of arguments"); + + return {__begin, uint32_t(__value)}; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + __parse_number_result<_CharT> __r = __parse_number(__begin, __end); + __parse_ctx.check_arg_id(__r.__value); + return __r; +} + +} // namespace __detail + +/** + * Parses a number. + * + * The number is used for the 31-bit values @em width and @em precision. This + * allows a maximum value of 2147483647. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end_input) { + static_assert(__format::__number_max == INT32_MAX, + "The algorithm is implemented based on this value."); + /* + * Limit the input to 9 digits, otherwise we need two checks during every + * iteration: + * - Are we at the end of the input? + * - Does the value exceed width of an uint32_t? (Switching to uint64_t would + * have the same issue, but with a higher maximum.) + */ + const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; + uint32_t __value = *__begin - _CharT('0'); + while (++__begin != __end) { + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return {__begin, __value}; + + __value = __value * 10 + *__begin - _CharT('0'); + } + + if (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9')) { + + /* + * There are more than 9 digits, do additional validations: + * - Does the 10th digit exceed the maximum allowed value? + * - Are there more than 10 digits? + * (More than 10 digits always overflows the maximum.) + */ + uint64_t __v = uint64_t(__value) * 10 + *__begin++ - _CharT('0'); + if (__v > __number_max || + (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9'))) + __throw_format_error("The numeric value of the format-spec is too large"); + + __value = __v; + } + + return {__begin, __value}; +} + +/** + * Multiplexer for all parse functions. + * + * The parser will return a pointer beyond the last consumed character. This + * should be the closing '}' of the arg-id. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + switch (*__begin) { + case _CharT('0'): + return __detail::__parse_zero(__begin, __end, __parse_ctx); + + case _CharT(':'): + // This case is conditionally valid. It's allowed in an arg-id in the + // replacement-field, but not in the std-format-spec. The caller can + // provide a better diagnostic, so accept it here unconditionally. + case _CharT('}'): + return __detail::__parse_automatic(__begin, __end, __parse_ctx); + } + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + __throw_format_error( + "The arg-id of the format-spec starts with an invalid character"); + + return __detail::__parse_manual(__begin, __end, __parse_ctx); +} + +} // namespace __format + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_STRING_H diff --git a/include/__format/format_to_n_result.h b/include/__format/format_to_n_result.h new file mode 100644 index 000000000..b973dc5c1 --- /dev/null +++ b/include/__format/format_to_n_result.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___FORMAT_FORMAT_TO_N_RESULT_H +#define _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H + +#include <__config> +#include <__iterator/incrementable_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 +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 + +#endif // _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H diff --git a/include/__format/formatter.h b/include/__format/formatter.h new file mode 100644 index 000000000..38b73bba3 --- /dev/null +++ b/include/__format/formatter.h @@ -0,0 +1,290 @@ +// -*- 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_H +#define _LIBCPP___FORMAT_FORMATTER_H + +#include <__algorithm/copy.h> +#include <__algorithm/fill_n.h> +#include <__availability> +#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 +#include + +#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 + +// 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 +/// If F is a disabled specialization of formatter, these values are false: +/// - is_default_constructible_v, +/// - is_copy_constructible_v, +/// - is_move_constructible_v, +/// - is_copy_assignable, and +/// - is_move_assignable. +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +namespace __format_spec { + +_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, + _Flags::_Sign __sign) { + if (__negative) + *__buf++ = '-'; + else + switch (__sign) { + case _Flags::_Sign::__default: + case _Flags::_Sign::__minus: + // No sign added. + break; + case _Flags::_Sign::__plus: + *__buf++ = '+'; + break; + case _Flags::_Sign::__space: + *__buf++ = ' '; + break; + } + + return __buf; +} + +_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; +} + +} // namespace __format_spec + +namespace __formatter { + +/** The character types that formatters are specialized for. */ +template +concept __char_type = same_as<_CharT, char> || same_as<_CharT, wchar_t>; + +struct _LIBCPP_TEMPLATE_VIS __padding_size_result { + size_t __before; + size_t __after; +}; + +_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result +__padding_size(size_t __size, size_t __width, + __format_spec::_Flags::_Alignment __align) { + _LIBCPP_ASSERT(__width > __size, + "Don't call this function when no padding is required"); + _LIBCPP_ASSERT( + __align != __format_spec::_Flags::_Alignment::__default, + "Caller should adjust the default to the value required by the type"); + + size_t __fill = __width - __size; + switch (__align) { + case __format_spec::_Flags::_Alignment::__default: + _LIBCPP_UNREACHABLE(); + + case __format_spec::_Flags::_Alignment::__left: + return {0, __fill}; + + case __format_spec::_Flags::_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::_Flags::_Alignment::__right: + return {__fill, 0}; + } + _LIBCPP_UNREACHABLE(); +} + +/** + * 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 input. + * + * @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 __out_it The output iterator to write to. + * @param __first Pointer to the first element to write. + * @param __last Pointer beyond the last element to write. + * @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. + * @param __width The number of output columns to write. + * @param __fill The character used for the alignment of the output. + * TODO FMT Will probably change to support Unicode grapheme + * cluster. + * @param __alignment The requested alignment. + * + * @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 __fill. 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 +_LIBCPP_HIDE_FROM_ABI auto +__write(output_iterator auto __out_it, const _CharT* __first, + const _CharT* __last, size_t __size, size_t __width, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) { + + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__size < __width, "Precondition failure"); + + __padding_size_result __padding = + __padding_size(__size, __width, __alignment); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it)); + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +/** + * @overload + * + * Writes additional zero's for the precision before the exponent. + * This is used when the precision requested in the format string is larger + * than the maximum precision of the floating-point type. These precision + * digits are always 0. + * + * @param __exponent The location of the exponent character. + * @param __num_trailing_zeros The number of 0's to write before the exponent + * character. + */ +template +_LIBCPP_HIDE_FROM_ABI auto __write(output_iterator auto __out_it, const _CharT* __first, + const _CharT* __last, size_t __size, size_t __width, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it)); + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +/** + * @overload + * + * Uses a transformation operation before writing an element. + * + * TODO FMT Fill will probably change to support Unicode grapheme cluster. + */ +template +_LIBCPP_HIDE_FROM_ABI auto +__write(output_iterator auto __out_it, const _CharT* __first, + const _CharT* __last, size_t __size, _UnaryOperation __op, + size_t __width, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) { + + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__size < __width, "Precondition failure"); + + __padding_size_result __padding = + __padding_size(__size, __width, __alignment); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op); + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +/** + * Writes Unicode input to the output with the required padding. + * + * This function does almost the same as the @ref __write function, but handles + * the width estimation of the Unicode input. + * + * @param __str The range [@a __first, @a __last). + * @param __precision The width to truncate the input string to, use @c -1 for + * no limit. + */ +template +_LIBCPP_HIDE_FROM_ABI auto +__write_unicode(output_iterator auto __out_it, + basic_string_view<_CharT> __str, ptrdiff_t __width, + ptrdiff_t __precision, _Fill __fill, + __format_spec::_Flags::_Alignment __alignment) + -> decltype(__out_it) { + + // This value changes when there Unicode column width limits the output + // size. + auto __last = __str.end(); + if (__width != 0 || __precision != -1) { + __format_spec::__string_alignment<_CharT> __format_traits = + __format_spec::__get_string_alignment(__str.begin(), __str.end(), + __width, __precision); + + if (__format_traits.__align) + return __write(_VSTD::move(__out_it), __str.begin(), + __format_traits.__last, __format_traits.__size, __width, + __fill, __alignment); + + // No alignment required update the output based on the precision. + // This might be the same as __str.end(). + __last = __format_traits.__last; + } + + // Copy the input to the output. The output size might be limited by the + // precision. + return _VSTD::copy(__str.begin(), __last, _VSTD::move(__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/include/__format/formatter_bool.h b/include/__format/formatter_bool.h new file mode 100644 index 000000000..1e40bc0a4 --- /dev/null +++ b/include/__format/formatter_bool.h @@ -0,0 +1,147 @@ +// -*- 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_BOOL_H +#define _LIBCPP___FORMAT_FORMATTER_BOOL_H + +#include <__availability> +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 _LIBCPP_TEMPLATE_VIS __parser_bool : 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::__string; + [[fallthrough]]; + case _Flags::_Type::__string: + this->__handle_bool(); + break; + + 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 bool argument"); + } + + return __it; + } +}; + +template +struct _LIBCPP_TEMPLATE_VIS __bool_strings; + +template <> +struct _LIBCPP_TEMPLATE_VIS __bool_strings { + 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 { + static constexpr wstring_view __true{L"true"}; + static constexpr wstring_view __false{L"false"}; +}; +#endif + +template +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 + : 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(__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>(__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); + } +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H diff --git a/include/__format/formatter_char.h b/include/__format/formatter_char.h new file mode 100644 index 000000000..2131de077 --- /dev/null +++ b/include/__format/formatter_char.h @@ -0,0 +1,104 @@ +// -*- 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_CHAR_H +#define _LIBCPP___FORMAT_FORMATTER_CHAR_H + +#include <__availability> +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 _LIBCPP_TEMPLATE_VIS __parser_char : 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::__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; + } +}; + +template +using __formatter_char = __formatter_integral<__parser_char<_CharT>>; + +} // namespace __format_spec + +// [format.formatter.spec]/2.1 The specializations + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_char {}; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_char { + using _Base = __format_spec::__formatter_char; + + _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) + -> decltype(__ctx.out()) { + return _Base::format(static_cast(__value), __ctx); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_char {}; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_CHAR_H diff --git a/include/__format/formatter_floating_point.h b/include/__format/formatter_floating_point.h new file mode 100644 index 000000000..2e710b409 --- /dev/null +++ b/include/__format/formatter_floating_point.h @@ -0,0 +1,717 @@ +// -*- 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_FLOATING_POINT_H +#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H + +#include <__algorithm/copy.h> +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/find.h> +#include <__algorithm/min.h> +#include <__algorithm/rotate.h> +#include <__algorithm/transform.h> +#include <__concepts/arithmetic.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 <__utility/move.h> +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#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 + +// 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 +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +// https://en.cppreference.com/w/cpp/language/types#cite_note-1 +// float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38 +// double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308 +// long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932 +// +// The maximum number of digits required for the integral part is based on the +// maximum's value power of 10. Every power of 10 requires one additional +// decimal digit. +// The maximum number of digits required for the fractional part is based on +// the minimal subnormal hexadecimal output's power of 10. Every division of a +// fraction's binary 1 by 2, requires one additional decimal digit. +// +// The maximum size of a formatted value depends on the selected output format. +// Ignoring the fact the format string can request a precision larger than the +// values maximum required, these values are: +// +// sign 1 code unit +// __max_integral +// radix point 1 code unit +// __max_fractional +// exponent character 1 code unit +// sign 1 code unit +// __max_fractional_value +// ----------------------------------- +// total 4 code units extra required. +// +// TODO FMT Optimize the storage to avoid storing digits that are known to be zero. +// https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/ + +// TODO FMT Add long double specialization when to_chars has proper long double support. +template +struct __traits; + +template +static constexpr size_t __float_buffer_size(int __precision) { + using _Traits = __traits<_Fp>; + return 4 + _Traits::__max_integral + __precision + _Traits::__max_fractional_value; +} + +template <> +struct __traits { + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; + static constexpr int __max_fractional_value = 3; + static constexpr size_t __stack_buffer_size = 256; + + static constexpr int __hex_precision_digits = 3; +}; + +template <> +struct __traits { + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; + static constexpr int __max_fractional_value = 4; + static constexpr size_t __stack_buffer_size = 1024; + + static constexpr int __hex_precision_digits = 4; +}; + +/// Helper class to store the conversion buffer. +/// +/// Depending on the maxium size required for a value, the buffer is allocated +/// on the stack or the heap. +template +class _LIBCPP_TEMPLATE_VIS __float_buffer { + using _Traits = __traits<_Fp>; + +public: + // TODO FMT Improve this constructor to do a better estimate. + // When using a scientific formatting with a precision of 6 a stack buffer + // will always suffice. At the moment that isn't important since floats and + // doubles use a stack buffer, unless the precision used in the format string + // is large. + // When supporting long doubles the __max_integral part becomes 4932 which + // may be too much for some platforms. For these cases a better estimate is + // required. + explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) + : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { + + // When the precision is larger than _Traits::__max_fractional the digits in + // the range (_Traits::__max_fractional, precision] will contain the value + // zero. There's no need to request to_chars to write these zeros: + // - When the value is large a temporary heap buffer needs to be allocated. + // - When to_chars writes the values they need to be "copied" to the output: + // - char: std::fill on the output iterator is faster than std::copy. + // - wchar_t: same argument as char, but additional std::copy won't work. + // The input is always a char buffer, so every char in the buffer needs + // to be converted from a char to a wchar_t. + if (__precision_ > _Traits::__max_fractional) { + __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; + } + + __size_ = __format_spec::__float_buffer_size<_Fp>(__precision_); + if (__size_ > _Traits::__stack_buffer_size) + // The allocated buffer's contents don't need initialization. + __begin_ = allocator{}.allocate(__size_); + else + __begin_ = __buffer_; + } + + _LIBCPP_HIDE_FROM_ABI ~__float_buffer() { + if (__size_ > _Traits::__stack_buffer_size) + allocator{}.deallocate(__begin_, __size_); + } + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; + + _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } + _LIBCPP_HIDE_FROM_ABI char* end() const { return __begin_ + __size_; } + + _LIBCPP_HIDE_FROM_ABI int __precision() const { return __precision_; } + _LIBCPP_HIDE_FROM_ABI int __num_trailing_zeros() const { return __num_trailing_zeros_; } + _LIBCPP_HIDE_FROM_ABI void __remove_trailing_zeros() { __num_trailing_zeros_ = 0; } + +private: + int __precision_; + int __num_trailing_zeros_{0}; + size_t __size_; + char* __begin_; + char __buffer_[_Traits::__stack_buffer_size]; +}; + +struct __float_result { + /// Points at the beginning of the integral part in the buffer. + /// + /// When there's no sign character this points at the start of the buffer. + char* __integral; + + /// Points at the radix point, when not present it's the same as \ref __last. + char* __radix_point; + + /// Points at the exponent character, when not present it's the same as \ref __last. + char* __exponent; + + /// Points beyond the last written element in the buffer. + char* __last; +}; + +/// Finds the position of the exponent character 'e' at the end of the buffer. +/// +/// Assuming there is an exponent the input will terminate with +/// eSdd and eSdddd (S = sign, d = digit) +/// +/// \returns a pointer to the exponent or __last when not found. +constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { + ptrdiff_t __size = __last - __first; + if (__size > 4) { + __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + for (; __first != __last - 3; ++__first) { + if (*__first == 'e') + return __first; + } + } + return __last; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value); + + __result.__exponent = __format_spec::__find_exponent(__result.__integral, __result.__last); + + // Constrains: + // - There's at least one decimal digit before the radix point. + // - The radix point, when present, is placed before the exponent. + __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + + // When the radix point isn't found its position is the exponent instead of + // __result.__last. + if (__result.__radix_point == __result.__exponent) + __result.__radix_point = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + if (__precision == -1) + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex); + else + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision); + + // H = one or more hex-digits + // S = sign + // D = one or more decimal-digits + // When the fractional part is zero and no precision the output is 0p+0 + // else the output is 0.HpSD + // So testing the second position can differentiate between these two cases. + char* __first = __integral + 1; + if (*__first == '.') { + __result.__radix_point = __first; + // One digit is the minimum + // 0.hpSd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456 + // + // Four digits is the maximum + // 0.hpSdddd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456789 + static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); + + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = _VSTD::find(__first, __last, 'p'); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); + _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + *__result.__exponent = 'P'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = + __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); + + char* __first = __integral + 1; + _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + if (*__first == '.') { + __result.__radix_point = __first; + __result.__exponent = __format_spec::__find_exponent(__first + 1, __result.__last); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); + *__result.__exponent = 'E'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); + + // When there's no precision there's no radix point. + // Else the radix point is placed at __precision + 1 from the end. + // By converting __precision to a bool the subtraction can be done + // unconditionally. + __result.__radix_point = __result.__last - (__precision + bool(__precision)); + __result.__exponent = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + + __buffer.__remove_trailing_zeros(); + + __float_result __result; + __result.__integral = __integral; + __result.__last = __format_spec::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision); + + char* __first = __integral + 1; + if (__first == __result.__last) { + __result.__radix_point = __result.__last; + __result.__exponent = __result.__last; + } else { + __result.__exponent = __format_spec::__find_exponent(__first, __result.__last); + if (__result.__exponent != __result.__last) + // In scientific mode if there's a radix point it will always be after + // the first digit. (This is the position __first points at). + __result.__radix_point = *__first == '.' ? __first : __result.__last; + else { + // In fixed mode the algorithm truncates trailing spaces and possibly the + // radix point. There's no good guess for the position of the radix point + // therefore scan the output after the first digit. + __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + } + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result = + __format_spec::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); + if (__result.__exponent != __result.__last) + *__result.__exponent = 'E'; + return __result; +} + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION +template +_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(_OutIt __out_it, const __float_buffer<_Fp>& __buffer, + const __float_result& __result, _VSTD::locale __loc, + size_t __width, _Flags::_Alignment __alignment, + _CharT __fill) { + const auto& __np = use_facet>(__loc); + string __grouping = __np.grouping(); + char* __first = __result.__integral; + // When no radix point or exponent are present __last will be __result.__last. + char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + + ptrdiff_t __digits = __last - __first; + if (!__grouping.empty()) { + if (__digits <= __grouping[0]) + __grouping.clear(); + else + __grouping = __determine_grouping(__digits, __grouping); + } + + size_t __size = __result.__last - __buffer.begin() + // Formatted string + __buffer.__num_trailing_zeros() + // Not yet rendered zeros + __grouping.size() - // Grouping contains one + !__grouping.empty(); // additional character + + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __alignment == _Flags::_Alignment::__default; + if (__size < __width) { + if (__zero_padding) { + __alignment = _Flags::_Alignment::__right; + __fill = _CharT('0'); + } + + __padding = __formatter::__padding_size(__size, __width, __alignment); + } + + // sign and (zero padding or alignment) + if (__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill); + if (!__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + + // integral part + if (__grouping.empty()) { + __out_it = _VSTD::copy_n(__first, __digits, _VSTD::move(__out_it)); + } else { + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _CharT __sep = __np.thousands_sep(); + // 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. + while (true) { + __out_it = _VSTD::copy_n(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + } + + // fractional part + if (__result.__radix_point != __result.__last) { + *__out_it++ = __np.decimal_point(); + __out_it = _VSTD::copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); + __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + } + + // exponent + if (__result.__exponent != __result.__last) + __out_it = _VSTD::copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + + // alignment + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill); +} + +# endif // _LIBCPP_HAS_NO_LOCALIZATION + +template <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_floating_point : public __parser_floating_point<_CharT> { +public: + template + _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)); + + bool __negative = _VSTD::signbit(__value); + + if (!_VSTD::isfinite(__value)) [[unlikely]] + return __format_non_finite(__ctx.out(), __negative, _VSTD::isnan(__value)); + + bool __has_precision = this->__has_precision_field(); + if (this->__precision_needs_substitution()) + this->__substitute_precision_arg_id(__ctx.arg(this->__precision)); + + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a non negative value. + // The function @ref __insert_sign will insert a '-' when the value was + // negative. + + if (__negative) + __value = _VSTD::copysign(__value, +1.0); + + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + using _Fp = conditional_t, double, _Tp>; + // Force the type of the precision to avoid -1 to become an unsigned value. + __float_buffer<_Fp> __buffer(__has_precision ? int(this->__precision) : -1); + __float_result __result = __format_buffer(__buffer, __value, __negative, __has_precision); + + if (this->__alternate_form && __result.__radix_point == __result.__last) { + *__result.__last++ = '.'; + + // When there is an exponent the point needs to be moved before the + // exponent. When there's no exponent the rotate does nothing. Since + // rotate tests whether the operation is a nop, call it unconditionally. + _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + __result.__radix_point = __result.__exponent; + + // The radix point is always placed before the exponent. + // - No exponent needs to point to the new last. + // - An exponent needs to move one position to the right. + // So it's safe to increment the value unconditionally. + ++__result.__exponent; + } + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (this->__locale_specific_form) + return __format_spec::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), + this->__width, this->__alignment, this->__fill); +# endif + + ptrdiff_t __size = __result.__last - __buffer.begin(); + int __num_trailing_zeros = __buffer.__num_trailing_zeros(); + if (__size + __num_trailing_zeros >= this->__width) { + if (__num_trailing_zeros && __result.__exponent != __result.__last) + // Insert trailing zeros before exponent character. + return _VSTD::copy(__result.__exponent, __result.__last, + _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__exponent, __ctx.out()), + __num_trailing_zeros, _CharT('0'))); + + return _VSTD::fill_n(_VSTD::copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, + _CharT('0')); + } + + auto __out_it = __ctx.out(); + char* __first = __buffer.begin(); + if (this->__alignment == _Flags::_Alignment::__default) { + // When there is a sign output it before the padding. Note the __size + // doesn't need any adjustment, regardless whether the sign is written + // here or in __formatter::__write. + if (__first != __result.__integral) + *__out_it++ = *__first++; + // After the sign is written, zero padding is the same a right alignment + // with '0'. + this->__alignment = _Flags::_Alignment::__right; + this->__fill = _CharT('0'); + } + + if (__num_trailing_zeros) + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment, __result.__exponent, __num_trailing_zeros); + + return __formatter::__write(_VSTD::move(__out_it), __first, __result.__last, __size, this->__width, this->__fill, + this->__alignment); + } + +private: + template + _LIBCPP_HIDE_FROM_ABI _OutIt __format_non_finite(_OutIt __out_it, bool __negative, bool __isnan) { + char __buffer[4]; + char* __last = __insert_sign(__buffer, __negative, this->__sign); + + // to_char can return inf, infinity, nan, and nan(n-char-sequence). + // The format library requires inf and nan. + // All in one expression to avoid dangling references. + __last = _VSTD::copy_n(&("infnanINFNAN"[6 * (this->__type == _Flags::_Type::__float_hexadecimal_upper_case || + this->__type == _Flags::_Type::__scientific_upper_case || + this->__type == _Flags::_Type::__fixed_upper_case || + this->__type == _Flags::_Type::__general_upper_case) + + 3 * __isnan]), + 3, __last); + + // [format.string.std]/13 + // A zero (0) character preceding the width field pads the field with + // leading zeros (following any indication of sign or base) to the field + // width, except when applied to an infinity or NaN. + if (this->__alignment == _Flags::_Alignment::__default) + this->__alignment = _Flags::_Alignment::__right; + + ptrdiff_t __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy_n(__buffer, __size, _VSTD::move(__out_it)); + + return __formatter::__write(_VSTD::move(__out_it), __buffer, __last, __size, this->__width, this->__fill, + this->__alignment); + } + + /// Fills the buffer with the data based on the requested formatting. + /// + /// This function, when needed, turns the characters to upper case and + /// determines the "interesting" locations which are returned to the caller. + /// + /// This means the caller never has to convert the contents of the buffer to + /// upper case or search for radix points and the location of the exponent. + /// This gives a bit of overhead. The original code didn't do that, but due + /// to the number of possible additional work needed to turn this number to + /// the proper output the code was littered with tests for upper cases and + /// searches for radix points and exponents. + /// - When a precision larger than the type's precision is selected + /// additional zero characters need to be written before the exponent. + /// - alternate form needs to add a radix point when not present. + /// - localization needs to do grouping in the integral part. + template + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(__float_buffer<_Fp>& __buffer, _Tp __value, bool __negative, + bool __has_precision) { + char* __first = __insert_sign(__buffer.begin(), __negative, this->__sign); + switch (this->__type) { + case _Flags::_Type::__default: + return __format_spec::__format_buffer_default(__buffer, __value, __first); + + case _Flags::_Type::__float_hexadecimal_lower_case: + return __format_spec::__format_buffer_hexadecimal_lower_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__float_hexadecimal_upper_case: + return __format_spec::__format_buffer_hexadecimal_upper_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case _Flags::_Type::__scientific_lower_case: + return __format_spec::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__scientific_upper_case: + return __format_spec::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + return __format_spec::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_lower_case: + return __format_spec::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case _Flags::_Type::__general_upper_case: + return __format_spec::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); + + default: + _LIBCPP_ASSERT(false, "The parser should have validated the type"); + _LIBCPP_UNREACHABLE(); + } + } +}; + +} //namespace __format_spec + +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_floating_point<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_floating_point<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H diff --git a/include/__format/formatter_integer.h b/include/__format/formatter_integer.h new file mode 100644 index 000000000..e1f3d4e34 --- /dev/null +++ b/include/__format/formatter_integer.h @@ -0,0 +1,170 @@ +// -*- 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_INTEGER_H +#define _LIBCPP___FORMAT_FORMATTER_INTEGER_H + +#include <__availability> +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include + +#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 + +// 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 _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; + } +}; + +template +using __formatter_integer = __formatter_integral<__parser_integer<_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 + +// Signed integral types. +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__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>; + + _LIBCPP_HIDE_FROM_ABI auto format(__int128_t __value, auto& __ctx) + -> 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"); + + return _Base::format(static_cast<_To>(__value), __ctx); + } +}; +#endif + +// Unsigned integral types. +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_integer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__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>; + + _LIBCPP_HIDE_FROM_ABI auto format(__uint128_t __value, auto& __ctx) + -> 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"); + + return _Base::format(static_cast<_To>(__value), __ctx); + } +}; +#endif + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H diff --git a/include/__format/formatter_integral.h b/include/__format/formatter_integral.h new file mode 100644 index 000000000..f164ee610 --- /dev/null +++ b/include/__format/formatter_integral.h @@ -0,0 +1,463 @@ +// -*- 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_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 <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/formatter.h> +#include <__format/parser_std_format_spec.h> +#include +#include +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#endif + +#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 + +// 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) + +/** + * 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 +_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 +_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 +_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. +} + +template +_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. +} + +template +_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. +} + +/** + * Determines the required grouping based on the size of the input. + * + * The grouping's last element will be repeated. For simplicity this repeating + * is unwrapped based on the length of the input. (When the input is short some + * groups are not processed.) + * + * @returns The size of the groups to write. This means the number of + * separator characters written is size() - 1. + * + * @note Since zero-sized groups cause issues they are silently ignored. + * + * @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_ASSERT(!__grouping.empty() && __size > __grouping[0], + "The slow grouping formatting is used while there will be no " + "separators written"); + string __r; + auto __end = __grouping.end() - 1; + auto __ptr = __grouping.begin(); + + while (true) { + __size -= *__ptr; + if (__size > 0) + __r.push_back(*__ptr); + else { + // __size <= 0 so the value pushed will be <= *__ptr. + __r.push_back(*__ptr + __size); + return __r; + } + + // Proceed to the next group. + if (__ptr != __end) { + do { + ++__ptr; + // Skip grouping with a width of 0. + } while (*__ptr == 0 && __ptr != __end); + } + } + + _LIBCPP_UNREACHABLE(); +} + +template +requires __formatter::__char_type +class _LIBCPP_TEMPLATE_VIS __formatter_integral : public _Parser { +public: + using _CharT = typename _Parser::char_type; + + template + _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); + + 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); + } + } + +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>(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>(__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 __write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1, + __ctx.out()); + } + + /** + * 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()> __array; + return __format_unsigned_integral(__array.begin(), __array.end(), __value, + __negative, 2, __ctx, "0b"); + } + case _Flags::_Type::__binary_upper_case: { + array()> __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()> __array; + return __format_unsigned_integral(__array.begin(), __array.end(), __value, + __negative, 8, __ctx, + __value != 0 ? "0" : nullptr); + } + case _Flags::_Type::__decimal: { + array()> __array; + return __format_unsigned_integral(__array.begin(), __array.end(), __value, + __negative, 10, __ctx, nullptr); + } + case _Flags::_Type::__hexadecimal_lower_case: { + array()> __array; + return __format_unsigned_integral(__array.begin(), __array.end(), __value, + __negative, 16, __ctx, "0x"); + } + case _Flags::_Type::__hexadecimal_upper_case: { + array()> __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(); + } + } + + template + requires(same_as || same_as) _LIBCPP_HIDE_FROM_ABI + auto __write(const _Tp* __first, const _Tp* __last, auto __out_it) + -> decltype(__out_it) { + + 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)); + + return __formatter::__write(_VSTD::move(__out_it), __first, __last, + __size, this->__width, this->__fill, + this->__alignment); + } + + // 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); + } + + _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>(__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); + } + + return __write(__first, __last, _VSTD::move(__out_it)); + } + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + /** Format's the locale-specific form's groupings. */ + template + _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)); + } + + 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; + } + + return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, + this->__fill); + } +#endif // _LIBCPP_HAS_NO_LOCALIZATION +}; + +} // namespace __format_spec + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H diff --git a/include/__format/formatter_pointer.h b/include/__format/formatter_pointer.h new file mode 100644 index 000000000..aa2eb641c --- /dev/null +++ b/include/__format/formatter_pointer.h @@ -0,0 +1,91 @@ +// -*- 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_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/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/access.h> +#include <__nullptr> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_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 <__formatter::__char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatter_pointer : public __parser_pointer<_CharT> { +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)); + + // 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(__ptr), 16); + + unsigned __size = __last - __buffer; + if (__size >= this->__width) + return _VSTD::copy(__buffer, __last, __ctx.out()); + + return __formatter::__write(__ctx.out(), __buffer, __last, __size, this->__width, this->__fill, this->__alignment); + } +}; + +} // namespace __format_spec + +// [format.formatter.spec]/2.4 +// For each charT, the pointer type specializations template<> +// - struct formatter; +// - template<> struct formatter; +// - template<> struct formatter; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_pointer<_CharT> {}; +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __format_spec::__formatter_pointer<_CharT> {}; + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H diff --git a/include/__format/formatter_string.h b/include/__format/formatter_string.h new file mode 100644 index 000000000..04950faa4 --- /dev/null +++ b/include/__format/formatter_string.h @@ -0,0 +1,162 @@ +// -*- 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_STRING_H +#define _LIBCPP___FORMAT_FORMATTER_STRING_H + +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_string.h> +#include <__format/formatter.h> +#include <__format/parser_std_format_spec.h> +#include + +#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 + +// 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> { +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); + } +}; + +} //namespace __format_spec + +// [format.formatter.spec]/2.2 For each charT, the string type specializations + +// Formatter const char*. +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_string<_CharT> { + using _Base = __format_spec::__formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) + -> decltype(__ctx.out()) { + _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have " + "prevented an invalid pointer."); + + // When using a center or right alignment and the width option the length + // of __str must be known to add the padding upfront. This case is handled + // by the base class by converting the argument to a basic_string_view. + // + // When using left alignment and the width option the padding is added + // after outputting __str so the length can be determined while outputting + // __str. The same holds true for the precision, during outputting __str it + // can be validated whether the precision threshold has been reached. For + // 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); + + // No formatting required, copy the string to the output. + auto __out_it = __ctx.out(); + while (*__str) + *__out_it++ = *__str++; + return __out_it; + } +}; + +// Formatter char*. +template <__formatter::__char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter<_CharT*, _CharT> : public formatter { + using _Base = formatter; + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) + -> decltype(__ctx.out()) { + return _Base::format(__str, __ctx); + } +}; + +// Formatter const char[]. +template <__formatter::__char_type _CharT, size_t _Size> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter + : public __format_spec::__formatter_string<_CharT> { + using _Base = __format_spec::__formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) + -> 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, _CharT> + : public __format_spec::__formatter_string<_CharT> { + using _Base = __format_spec::__formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto + format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) + -> decltype(__ctx.out()) { + // drop _Traits and _Allocator + return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); + } +}; + +// Formatter std::string_view. +template <__formatter::__char_type _CharT, class _Traits> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __format_spec::__formatter_string<_CharT> { + using _Base = __format_spec::__formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto + format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) + -> decltype(__ctx.out()) { + // drop _Traits + 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/include/__format/parser_std_format_spec.h b/include/__format/parser_std_format_spec.h new file mode 100644 index 000000000..9d893e9ce --- /dev/null +++ b/include/__format/parser_std_format_spec.h @@ -0,0 +1,1398 @@ +// -*- 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_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H + +#include <__algorithm/find_if.h> +#include <__algorithm/min.h> +#include <__config> +#include <__debug> +#include <__format/format_arg.h> +#include <__format/format_error.h> +#include <__format/format_string.h> +#include <__variant/monostate.h> +#include +#include +#include +#include + +#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 + +// 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 + * 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. + */ +class _LIBCPP_TYPE_VIS _Flags { +public: + enum class _LIBCPP_ENUM_VIS _Alignment : uint8_t { + /** + * No alignment is set in the format string. + * + * Zero-padding is ignored when an alignment is selected. + * The default alignment depends on the selected format-type. + */ + __default, + __left, + __center, + __right + }; + 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 + }; + + _Alignment __alignment : 2 {_Alignment::__default}; + _Sign __sign : 2 {_Sign::__default}; + uint8_t __alternate_form : 1 {false}; + uint8_t __zero_padding : 1 {false}; + uint8_t __locale_specific_form : 1 {false}; + + 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, + __float_hexadecimal_lower_case, + __float_hexadecimal_upper_case, + __scientific_lower_case, + __scientific_upper_case, + __fixed_lower_case, + __fixed_upper_case, + __general_lower_case, + __general_upper_case + }; + + _Type __type{_Type::__default}; +}; + +namespace __detail { +template +_LIBCPP_HIDE_FROM_ABI constexpr bool +__parse_alignment(_CharT __c, _Flags& __flags) noexcept { + switch (__c) { + case _CharT('<'): + __flags.__alignment = _Flags::_Alignment::__left; + return true; + + case _CharT('^'): + __flags.__alignment = _Flags::_Alignment::__center; + return true; + + case _CharT('>'): + __flags.__alignment = _Flags::_Alignment::__right; + return true; + } + return false; +} +} // namespace __detail + +template +class _LIBCPP_TEMPLATE_VIS __parser_fill_align { +public: + // TODO FMT The standard doesn't specify this character is a Unicode + // character. Validate what fmt and MSVC have implemented. + _CharT __fill{_CharT(' ')}; + +protected: + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* + __parse(const _CharT* __begin, const _CharT* __end, _Flags& __flags) { + _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 (__detail::__parse_alignment(*(__begin + 1), __flags)) { + if (*__begin == _CharT('{') || *__begin == _CharT('}')) + __throw_format_error( + "The format-spec fill field contains an invalid character"); + __fill = *__begin; + return __begin + 2; + } + } + + if (__detail::__parse_alignment(*__begin, __flags)) + return __begin + 1; + + return __begin; + } +}; + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__parse_sign(const _CharT* __begin, _Flags& __flags) noexcept { + switch (*__begin) { + case _CharT('-'): + __flags.__sign = _Flags::_Sign::__minus; + break; + case _CharT('+'): + __flags.__sign = _Flags::_Sign::__plus; + break; + case _CharT(' '): + __flags.__sign = _Flags::_Sign::__space; + break; + default: + return __begin; + } + return __begin + 1; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__parse_alternate_form(const _CharT* __begin, _Flags& __flags) noexcept { + if (*__begin == _CharT('#')) { + __flags.__alternate_form = true; + ++__begin; + } + + return __begin; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__parse_zero_padding(const _CharT* __begin, _Flags& __flags) noexcept { + if (*__begin == _CharT('0')) { + __flags.__zero_padding = true; + ++__begin; + } + + return __begin; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + // This function is a wrapper to call the real parser. But it does the + // validation for the pre-conditions and post-conditions. + if (__begin == __end) + __throw_format_error("End of input while parsing format-spec arg-id"); + + __format::__parse_number_result __r = + __format::__parse_arg_id(__begin, __end, __parse_ctx); + + if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) + __throw_format_error("Invalid arg-id"); + + ++__r.__ptr; + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr uint32_t +__substitute_arg_id(basic_format_arg<_Context> __arg) { + return visit_format_arg( + [](auto __arg) -> uint32_t { + using _Type = decltype(__arg); + if constexpr (integral<_Type>) { + if constexpr (signed_integral<_Type>) { + if (__arg < 0) + __throw_format_error("A format-spec arg-id replacement shouldn't " + "have a negative value"); + } + + using _CT = common_type_t<_Type, decltype(__format::__number_max)>; + if (static_cast<_CT>(__arg) > + static_cast<_CT>(__format::__number_max)) + __throw_format_error("A format-spec arg-id replacement exceeds " + "the maximum supported value"); + + return __arg; + } else if constexpr (same_as<_Type, monostate>) + __throw_format_error("Argument index out of bounds"); + else + __throw_format_error("A format-spec arg-id replacement argument " + "isn't an integral type"); + }, + __arg); +} + +class _LIBCPP_TYPE_VIS __parser_width { +public: + /** Contains a width or an arg-id. */ + uint32_t __width : 31 {0}; + /** Determines whether the value stored is a width or an arg-id. */ + uint32_t __width_as_arg : 1 {0}; + +protected: + /** + * Does the supplied std-format-spec contain a width field? + * + * 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; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* + __parse(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 = + __parse_arg_id(++__begin, __end, __parse_ctx); + __width = __r.__value; + __width_as_arg = 1; + return __r.__ptr; + } + + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return __begin; + + __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"); + return __r.__ptr; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_width_arg_id(auto __arg) { + _LIBCPP_ASSERT(__width_as_arg == 1, + "Substitute width called when no substitution is required"); + + // The clearing of the flag isn't required but looks better when debugging + // the code. + __width_as_arg = 0; + __width = __substitute_arg_id(__arg); + if (__width == 0) + __throw_format_error( + "A format-spec width field replacement should have a positive value"); + } +}; + +class _LIBCPP_TYPE_VIS __parser_precision { +public: + /** Contains a precision or an arg-id. */ + uint32_t __precision : 31 {__format::__number_max}; + /** + * Determines whether the value stored is a precision or an arg-id. + * + * @note Since @ref __precision == @ref __format::__number_max is a valid + * value, the default value contains an arg-id of INT32_MAX. (This number of + * arguments isn't supported by compilers.) This is used to detect whether + * the std-format-spec contains a precision field. + */ + uint32_t __precision_as_arg : 1 {1}; + +protected: + /** + * Does the supplied std-format-spec contain a precision field? + * + * When the field isn't present there's no truncating required. This can be + * used to optimize the formatting. + */ + constexpr bool __has_precision_field() const noexcept { + + return __precision_as_arg == 0 || // Contains a value? + __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 + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* + __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + if (*__begin != _CharT('.')) + return __begin; + + ++__begin; + if (__begin == __end) + __throw_format_error("End of input while parsing format-spec precision"); + + if (*__begin == _CharT('{')) { + __format::__parse_number_result __arg_id = + __parse_arg_id(++__begin, __end, __parse_ctx); + _LIBCPP_ASSERT(__arg_id.__value != __format::__number_max, + "Unsupported number of arguments, since this number of " + "arguments is used a special value"); + __precision = __arg_id.__value; + return __arg_id.__ptr; + } + + 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 = 0; + return __r.__ptr; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_precision_arg_id( + auto __arg) { + _LIBCPP_ASSERT( + __precision_as_arg == 1 && __precision != __format::__number_max, + "Substitute precision called when no substitution is required"); + + // The clearing of the flag isn't required but looks better when debugging + // the code. + __precision_as_arg = 0; + __precision = __substitute_arg_id(__arg); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__parse_locale_specific_form(const _CharT* __begin, _Flags& __flags) noexcept { + if (*__begin == _CharT('L')) { + __flags.__locale_specific_form = true; + ++__begin; + } + + return __begin; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__parse_type(const _CharT* __begin, _Flags& __flags) { + + // 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': + __flags.__type = _Flags::_Type::__float_hexadecimal_upper_case; + break; + case 'B': + __flags.__type = _Flags::_Type::__binary_upper_case; + break; + case 'E': + __flags.__type = _Flags::_Type::__scientific_upper_case; + break; + case 'F': + __flags.__type = _Flags::_Type::__fixed_upper_case; + break; + case 'G': + __flags.__type = _Flags::_Type::__general_upper_case; + break; + case 'X': + __flags.__type = _Flags::_Type::__hexadecimal_upper_case; + break; + case 'a': + __flags.__type = _Flags::_Type::__float_hexadecimal_lower_case; + break; + case 'b': + __flags.__type = _Flags::_Type::__binary_lower_case; + break; + case 'c': + __flags.__type = _Flags::_Type::__char; + break; + case 'd': + __flags.__type = _Flags::_Type::__decimal; + break; + case 'e': + __flags.__type = _Flags::_Type::__scientific_lower_case; + break; + case 'f': + __flags.__type = _Flags::_Type::__fixed_lower_case; + break; + case 'g': + __flags.__type = _Flags::_Type::__general_lower_case; + break; + case 'o': + __flags.__type = _Flags::_Type::__octal; + break; + case 'p': + __flags.__type = _Flags::_Type::__pointer; + break; + case 's': + __flags.__type = _Flags::_Type::__string; + break; + case 'x': + __flags.__type = _Flags::_Type::__hexadecimal_lower_case; + break; + default: + return __begin; + } + return ++__begin; +} + +/** + * Process the parsed alignment and zero-padding state of arithmetic types. + * + * [format.string.std]/13 + * If the 0 character and an align option both appear, the 0 character is + * ignored. + * + * For the formatter a @ref __default alignment means zero-padding. + */ +_LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) { + __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default; + if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default) + __flags.__alignment = _Flags::_Alignment::__right; +} + +/** + * The parser for the std-format-spec. + * + * [format.string.std]/1 specifies the std-format-spec: + * fill-and-align sign # 0 width precision L type + * + * All these fields are optional. Whether these fields can be used depend on: + * - The type supplied to the format string. + * E.g. A string never uses the sign field so the field may not be set. + * This constrain is validated by the parsers in this file. + * - The supplied value for the optional type field. + * E.g. A int formatted as decimal uses the sign field. + * When formatted as a char the sign field may no longer be set. + * This constrain isn't validated by the parsers in this file. + * + * The base classes are ordered to minimize the amount of padding. + * + * This implements the parser for the string types. + */ +template +class _LIBCPP_TEMPLATE_VIS __parser_string + : public __parser_width, // provides __width(|as_arg) + public __parser_precision, // provides __precision(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr __parser_string() { + this->__alignment = _Flags::_Alignment::__left; + } + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_display_type(); + return __it; + } + +private: + /** + * Parses the std-format-spec. + * + * @throws __throw_format_error When @a __parse_ctx contains an ill-formed + * std-format-spec. + * + * @returns An iterator to the end of input or point at the closing '}'. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, + static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parser_precision::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error( + "The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + case _Flags::_Type::__string: + break; + + default: + __throw_format_error("The format-spec type has a type not supported for " + "a string argument"); + } + } +}; + +/** + * The parser for the std-format-spec. + * + * This implements the parser for the integral types. This includes the + * character type and boolean type. + * + * See @ref __parser_string. + */ +template +class _LIBCPP_TEMPLATE_VIS __parser_integral + : public __parser_width, // provides __width(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, + static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_sign(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = + __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error( + "The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Handles the post-parsing updates for the integer types. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept { + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); + } + + /** + * Handles the post-parsing updates for the character types. + * + * Sets the alignment and validates the format flags set for a character type. + * + * At the moment the validation for a character and a Boolean behave the + * same, but this may change in the future. + * Specifically at the moment the locale-specific form is allowed for the + * char output type, but it has no effect on the output. + */ + _LIBCPP_HIDE_FROM_ABI constexpr void __handle_char() { __handle_bool(); } + + /** + * Handles the post-parsing updates for the Boolean types. + * + * Sets the alignment and validates the format flags set for a Boolean type. + */ + _LIBCPP_HIDE_FROM_ABI constexpr void __handle_bool() { + if (this->__sign != _Flags::_Sign::__default) + __throw_format_error("A sign field isn't allowed in this format-spec"); + + if (this->__alternate_form) + __throw_format_error( + "An alternate form field isn't allowed in this format-spec"); + + if (this->__zero_padding) + __throw_format_error( + "A zero-padding field isn't allowed in this format-spec"); + + if (this->__alignment == _Flags::_Alignment::__default) + this->__alignment = _Flags::_Alignment::__left; + } +}; + +/** + * The parser for the std-format-spec. + * + * This implements the parser for the floating-point types. + * + * See @ref __parser_string. + */ +template +class _LIBCPP_TEMPLATE_VIS __parser_floating_point + : public __parser_width, // provides __width(|as_arg) + public __parser_precision, // provides __precision(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_arithmetic_alignment(static_cast<_Flags&>(*this)); + __process_display_type(); + return __it; + } +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, + static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_sign(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parser_precision::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = + __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error( + "The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + // When no precision specified then it keeps default since that + // formatting differs from the other types. + if (this->__has_precision_field()) + this->__type = _Flags::_Type::__general_lower_case; + break; + case _Flags::_Type::__float_hexadecimal_lower_case: + case _Flags::_Type::__float_hexadecimal_upper_case: + // Precision specific behavior will be handled later. + break; + case _Flags::_Type::__scientific_lower_case: + case _Flags::_Type::__scientific_upper_case: + case _Flags::_Type::__fixed_lower_case: + case _Flags::_Type::__fixed_upper_case: + case _Flags::_Type::__general_lower_case: + case _Flags::_Type::__general_upper_case: + if (!this->__has_precision_field()) { + // Set the default precision for the call to to_chars. + this->__precision = 6; + this->__precision_as_arg = false; + } + break; + + default: + __throw_format_error("The format-spec type has a type not supported for " + "a floating-point argument"); + } + } +}; + +/** + * The parser for the std-format-spec. + * + * This implements the parser for the pointer types. + * + * See @ref __parser_string. + */ +template +class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width, // provides __width(|as_arg) + public __parser_fill_align<_CharT>, // provides __fill and uses __flags + public _Flags // provides __flags +{ +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() { + // Implements LWG3612 Inconsistent pointer alignment in std::format. + // The issue's current status is "Tentatively Ready" and libc++ status is + // still experimental. + // + // TODO FMT Validate this with the final resolution of LWG3612. + this->__alignment = _Flags::_Alignment::__right; + } + + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __it = __parse(__parse_ctx); + __process_display_type(); + return __it; + } + +protected: + /** + * The low-level std-format-spec parse function. + * + * @pre __begin points at the beginning of the std-format-spec. This means + * directly after the ':'. + * @pre The std-format-spec parses the entire input, or the first unmatched + * character is a '}'. + * + * @returns The iterator pointing at the last parsed character. + */ + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this)); + if (__begin == __end) + return __begin; + + // An integer presentation type isn't defined in the Standard. + // Since a pointer is formatted as an integer it can be argued it's an + // integer presentation type. However there are two LWG-issues asserting it + // isn't an integer presentation type: + // - LWG3612 Inconsistent pointer alignment in std::format + // - LWG3644 std::format does not define "integer presentation type" + // + // There's a paper to make additional clarifications on the status of + // formatting pointers and proposes additional fields to be valid. That + // paper hasn't been reviewed by the Committee yet. + // - P2510 Formatting pointers + // + // The current implementation assumes formatting pointers isn't covered by + // "integer presentation type". + // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee. + + __begin = __parser_width::__parse(__begin, __end, __parse_ctx); + if (__begin == __end) + return __begin; + + __begin = __parse_type(__begin, static_cast<_Flags&>(*this)); + + if (__begin != __end && *__begin != _CharT('}')) + __throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + /** Processes the parsed std-format-spec based on the parsed display type. */ + _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() { + switch (this->__type) { + case _Flags::_Type::__default: + this->__type = _Flags::_Type::__pointer; + break; + case _Flags::_Type::__pointer: + break; + default: + __throw_format_error("The format-spec type has a type not supported for a pointer argument"); + } + } +}; + +/** Helper struct returned from @ref __get_string_alignment. */ +template +struct _LIBCPP_TEMPLATE_VIS __string_alignment { + /** Points beyond the last character to write to the output. */ + const _CharT* __last; + /** + * The estimated number of columns in the output or 0. + * + * Only when the output needs to be aligned it's required to know the exact + * number of columns in the output. So if the formatted output has only a + * minimum width the exact size isn't important. It's only important to know + * the minimum has been reached. The minimum width is the width specified in + * the format-spec. + * + * For example in this code @code std::format("{:10}", MyString); @endcode + * the width estimation can stop once the algorithm has determined the output + * width is 10 columns. + * + * So if: + * * @ref __align == @c true the @ref __size is the estimated number of + * columns required. + * * @ref __align == @c false the @ref __size is the estimated number of + * columns required or 0 when the estimation algorithm stopped prematurely. + */ + ptrdiff_t __size; + /** + * Does the output need to be aligned. + * + * When alignment is needed the output algorithm needs to add the proper + * padding. Else the output algorithm just needs to copy the input up to + * @ref __last. + */ + bool __align; +}; + +#ifndef _LIBCPP_HAS_NO_UNICODE +namespace __detail { + +/** + * Unicode column width estimates. + * + * Unicode can be stored in several formats: UTF-8, UTF-16, and UTF-32. + * Depending on format the relation between the number of code units stored and + * the number of output columns differs. The first relation is the number of + * code units forming a code point. (The text assumes the code units are + * unsigned.) + * - UTF-8 The number of code units is between one and four. The first 127 + * Unicode code points match the ASCII character set. When the highest bit is + * set it means the code point has more than one code unit. + * - UTF-16: The number of code units is between 1 and 2. When the first + * code unit is in the range [0xd800,0xdfff) it means the code point uses two + * code units. + * - UTF-32: The number of code units is always one. + * + * The code point to the number of columns isn't well defined. The code uses the + * estimations defined in [format.string.std]/11. This list might change in the + * future. + * + * The algorithm of @ref __get_string_alignment uses two different scanners: + * - The simple scanner @ref __estimate_column_width_fast. This scanner assumes + * 1 code unit is 1 column. This scanner stops when it can't be sure the + * assumption is valid: + * - UTF-8 when the code point is encoded in more than 1 code unit. + * - UTF-16 and UTF-32 when the first multi-column code point is encountered. + * (The code unit's value is lower than 0xd800 so the 2 code unit encoding + * is irrelevant for this scanner.) + * Due to these assumptions the scanner is faster than the full scanner. It + * can process all text only containing ASCII. For UTF-16/32 it can process + * most (all?) European languages. (Note the set it can process might be + * reduced in the future, due to updates in the scanning rules.) + * - The full scanner @ref __estimate_column_width. This scanner, if needed, + * converts multiple code units into one code point then converts the code + * point to a column width. + * + * See also: + * - [format.string.general]/11 + * - https://en.wikipedia.org/wiki/UTF-8#Encoding + * - https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + */ + +/** + * The first 2 column code point. + * + * This is the point where the fast UTF-16/32 scanner needs to stop processing. + */ +inline constexpr uint32_t __two_column_code_point = 0x1100; + +/** Helper concept for an UTF-8 character type. */ +template +concept __utf8_character = same_as<_CharT, char> || same_as<_CharT, char8_t>; + +/** Helper concept for an UTF-16 character type. */ +template +concept __utf16_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) || same_as<_CharT, char16_t>; + +/** Helper concept for an UTF-32 character type. */ +template +concept __utf32_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) || same_as<_CharT, char32_t>; + +/** Helper concept for an UTF-16 or UTF-32 character type. */ +template +concept __utf16_or_32_character = __utf16_character<_CharT> || __utf32_character<_CharT>; + +/** + * Converts a code point to the column width. + * + * The estimations are conforming to [format.string.general]/11 + * + * This version expects a value less than 0x1'0000, which is a 3-byte UTF-8 + * character. + */ +_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_3(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c < 0x1'0000, + "Use __column_width_4 or __column_width for larger values"); + + // clang-format off + return 1 + (__c >= 0x1100 && (__c <= 0x115f || + (__c >= 0x2329 && (__c <= 0x232a || + (__c >= 0x2e80 && (__c <= 0x303e || + (__c >= 0x3040 && (__c <= 0xa4cf || + (__c >= 0xac00 && (__c <= 0xd7a3 || + (__c >= 0xf900 && (__c <= 0xfaff || + (__c >= 0xfe10 && (__c <= 0xfe19 || + (__c >= 0xfe30 && (__c <= 0xfe6f || + (__c >= 0xff00 && (__c <= 0xff60 || + (__c >= 0xffe0 && (__c <= 0xffe6 + )))))))))))))))))))); + // clang-format on +} + +/** + * @overload + * + * This version expects a value greater than or equal to 0x1'0000, which is a + * 4-byte UTF-8 character. + */ +_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_4(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c >= 0x1'0000, + "Use __column_width_3 or __column_width for smaller values"); + + // clang-format off + return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f || + (__c >= 0x1'f900 && (__c <= 0x1'f9ff || + (__c >= 0x2'0000 && (__c <= 0x2'fffd || + (__c >= 0x3'0000 && (__c <= 0x3'fffd + )))))))); + // clang-format on +} + +/** + * @overload + * + * The general case, accepting all values. + */ +_LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width(uint32_t __c) noexcept { + if (__c < 0x1'0000) + return __column_width_3(__c); + + return __column_width_4(__c); +} + +/** + * Estimate the column width for the UTF-8 sequence using the fast algorithm. + */ +template <__utf8_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__estimate_column_width_fast(const _CharT* __first, + const _CharT* __last) noexcept { + return _VSTD::find_if(__first, __last, + [](unsigned char __c) { return __c & 0x80; }); +} + +/** + * @overload + * + * The implementation for UTF-16/32. + */ +template <__utf16_or_32_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__estimate_column_width_fast(const _CharT* __first, + const _CharT* __last) noexcept { + return _VSTD::find_if(__first, __last, + [](uint32_t __c) { return __c >= 0x1100; }); +} + +template +struct _LIBCPP_TEMPLATE_VIS __column_width_result { + /** The number of output columns. */ + size_t __width; + /** + * The last parsed element. + * + * This limits the original output to fit in the wanted number of columns. + */ + const _CharT* __ptr; +}; + +/** + * Small helper to determine the width of malformed Unicode. + * + * @note This function's only needed for UTF-8. During scanning UTF-8 there + * are multiple place where it can be detected that the Unicode is malformed. + * UTF-16 only requires 1 test and UTF-32 requires no testing. + */ +template <__utf8_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width_malformed(const _CharT* __first, const _CharT* __last, + size_t __maximum, size_t __result) noexcept { + size_t __size = __last - __first; + size_t __n = _VSTD::min(__size, __maximum); + return {__result + __n, __first + __n}; +} + +/** + * Determines the number of output columns needed to render the input. + * + * @note When the scanner encounters malformed Unicode it acts as-if every code + * unit at the end of the input is one output column. It's expected the output + * terminal will replace these malformed code units with a one column + * replacement characters. + * + * @param __first Points to the first element of the input range. + * @param __last Points beyond the last element of the input range. + * @param __maximum The maximum number of output columns. The returned number + * of estimated output columns will not exceed this value. + */ +template <__utf8_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width(const _CharT* __first, const _CharT* __last, + size_t __maximum) noexcept { + size_t __result = 0; + + while (__first != __last) { + // Based on the number of leading 1 bits the number of code units in the + // code point can be determined. See + // https://en.wikipedia.org/wiki/UTF-8#Encoding + switch (_VSTD::countl_one(static_cast(*__first))) { + case 0: // 1-code unit encoding: all 1 column + ++__result; + ++__first; + break; + + case 2: // 2-code unit encoding: all 1 column + // Malformed Unicode. + if (__last - __first < 2) [[unlikely]] + return __estimate_column_width_malformed(__first, __last, __maximum, + __result); + __first += 2; + ++__result; + break; + + case 3: // 3-code unit encoding: either 1 or 2 columns + // Malformed Unicode. + if (__last - __first < 3) [[unlikely]] + return __estimate_column_width_malformed(__first, __last, __maximum, + __result); + { + uint32_t __c = static_cast(*__first++) & 0x0f; + __c <<= 6; + __c |= static_cast(*__first++) & 0x3f; + __c <<= 6; + __c |= static_cast(*__first++) & 0x3f; + __result += __column_width_3(__c); + if (__result > __maximum) + return {__result - 2, __first - 3}; + } + break; + case 4: // 4-code unit encoding: either 1 or 2 columns + // Malformed Unicode. + if (__last - __first < 4) [[unlikely]] + return __estimate_column_width_malformed(__first, __last, __maximum, + __result); + { + uint32_t __c = static_cast(*__first++) & 0x07; + __c <<= 6; + __c |= static_cast(*__first++) & 0x3f; + __c <<= 6; + __c |= static_cast(*__first++) & 0x3f; + __c <<= 6; + __c |= static_cast(*__first++) & 0x3f; + __result += __column_width_4(__c); + if (__result > __maximum) + return {__result - 2, __first - 4}; + } + break; + default: + // Malformed Unicode. + return __estimate_column_width_malformed(__first, __last, __maximum, + __result); + } + + if (__result >= __maximum) + return {__result, __first}; + } + return {__result, __first}; +} + +template <__utf16_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width(const _CharT* __first, const _CharT* __last, + size_t __maximum) noexcept { + size_t __result = 0; + + while (__first != __last) { + uint32_t __c = *__first; + // Is the code unit part of a surrogate pair? See + // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + if (__c >= 0xd800 && __c <= 0xDfff) { + // Malformed Unicode. + if (__last - __first < 2) [[unlikely]] + return {__result + 1, __first + 1}; + + __c -= 0xd800; + __c <<= 10; + __c += (*(__first + 1) - 0xdc00); + __c += 0x10'000; + + __result += __column_width_4(__c); + if (__result > __maximum) + return {__result - 2, __first}; + __first += 2; + } else { + __result += __column_width_3(__c); + if (__result > __maximum) + return {__result - 2, __first}; + ++__first; + } + + if (__result >= __maximum) + return {__result, __first}; + } + + return {__result, __first}; +} + +template <__utf32_character _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width(const _CharT* __first, const _CharT* __last, + size_t __maximum) noexcept { + size_t __result = 0; + + while (__first != __last) { + wchar_t __c = *__first; + __result += __column_width(__c); + + if (__result > __maximum) + return {__result - 2, __first}; + + ++__first; + if (__result >= __maximum) + return {__result, __first}; + } + + return {__result, __first}; +} + +} // namespace __detail + +template +_LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT> +__get_string_alignment(const _CharT* __first, const _CharT* __last, + ptrdiff_t __width, ptrdiff_t __precision) noexcept { + _LIBCPP_ASSERT(__width != 0 || __precision != -1, + "The function has no effect and shouldn't be used"); + + // TODO FMT There might be more optimizations possible: + // If __precision == __format::__number_max and the encoding is: + // * UTF-8 : 4 * (__last - __first) >= __width + // * UTF-16 : 2 * (__last - __first) >= __width + // * UTF-32 : (__last - __first) >= __width + // In these cases it's certain the output is at least the requested width. + // It's unknown how often this happens in practice. For now the improvement + // isn't implemented. + + /* + * First assume there are no special Unicode code units in the input. + * - Apply the precision (this may reduce the size of the input). When + * __precison == -1 this step is omitted. + * - Scan for special code units in the input. + * If our assumption was correct the __pos will be at the end of the input. + */ + const ptrdiff_t __length = __last - __first; + const _CharT* __limit = + __first + + (__precision == -1 ? __length : _VSTD::min(__length, __precision)); + ptrdiff_t __size = __limit - __first; + const _CharT* __pos = + __detail::__estimate_column_width_fast(__first, __limit); + + if (__pos == __limit) + return {__limit, __size, __size < __width}; + + /* + * Our assumption was wrong, there are special Unicode code units. + * The range [__first, __pos) contains a set of code units with the + * following property: + * Every _CharT in the range will be rendered in 1 column. + * + * If there's no maximum width and the parsed size already exceeds the + * minimum required width. The real size isn't important. So bail out. + */ + if (__precision == -1 && (__pos - __first) >= __width) + return {__last, 0, false}; + + /* If there's a __precision, truncate the output to that width. */ + ptrdiff_t __prefix = __pos - __first; + if (__precision != -1) { + _LIBCPP_ASSERT(__precision > __prefix, "Logic error."); + auto __lengh_info = __detail::__estimate_column_width( + __pos, __last, __precision - __prefix); + __size = __lengh_info.__width + __prefix; + return {__lengh_info.__ptr, __size, __size < __width}; + } + + /* Else use __width to determine the number of required padding characters. */ + _LIBCPP_ASSERT(__width > __prefix, "Logic error."); + /* + * The column width is always one or two columns. For the precision the wanted + * column width is the maximum, for the width it's the minimum. Using the + * width estimation with its truncating behavior will result in the wrong + * result in the following case: + * - The last code unit processed requires two columns and exceeds the + * maximum column width. + * By increasing the __maximum by one avoids this issue. (It means it may + * pass one code point more than required to determine the proper result; + * that however isn't a problem for the algorithm.) + */ + size_t __maximum = 1 + __width - __prefix; + auto __lengh_info = + __detail::__estimate_column_width(__pos, __last, __maximum); + if (__lengh_info.__ptr != __last) { + // Consumed the width number of code units. The exact size of the string + // is unknown. We only know we don't need to align the output. + _LIBCPP_ASSERT(static_cast(__lengh_info.__width + __prefix) >= + __width, + "Logic error"); + return {__last, 0, false}; + } + + __size = __lengh_info.__width + __prefix; + return {__last, __size, __size < __width}; +} +#else // _LIBCPP_HAS_NO_UNICODE +template +_LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT> +__get_string_alignment(const _CharT* __first, const _CharT* __last, + ptrdiff_t __width, ptrdiff_t __precision) noexcept { + const ptrdiff_t __length = __last - __first; + const _CharT* __limit = + __first + + (__precision == -1 ? __length : _VSTD::min(__length, __precision)); + ptrdiff_t __size = __limit - __first; + return {__limit, __size, __size < __width}; +} +#endif // _LIBCPP_HAS_NO_UNICODE + +} // namespace __format_spec + +# endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H diff --git a/include/__functional/binary_function.h b/include/__functional/binary_function.h new file mode 100644 index 000000000..8ca7b0666 --- /dev/null +++ b/include/__functional/binary_function.h @@ -0,0 +1,31 @@ +// -*- 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_BINARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS binary_function +{ + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H diff --git a/include/__functional/binary_negate.h b/include/__functional/binary_negate.h new file mode 100644 index 000000000..4fc3f1ba2 --- /dev/null +++ b/include/__functional/binary_negate.h @@ -0,0 +1,50 @@ +// -*- 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_BINARY_NEGATE_H +#define _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H + +#include <__config> +#include <__functional/binary_function.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_NEGATORS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate + : public binary_function +{ + _Predicate __pred_; +public: + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + binary_negate(const _Predicate& __pred) : __pred_(__pred) {} + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + {return !__pred_(__x, __y);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +binary_negate<_Predicate> +not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H diff --git a/include/__functional/bind.h b/include/__functional/bind.h new file mode 100644 index 000000000..11a51e595 --- /dev/null +++ b/include/__functional/bind.h @@ -0,0 +1,392 @@ +// -*- 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_BIND_H +#define _LIBCPP___FUNCTIONAL_BIND_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/weak_result_type.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct is_bind_expression : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + false_type, + is_bind_expression::type> +> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; +#endif + +template +struct is_placeholder : _If< + _IsSame<_Tp, typename __uncvref<_Tp>::type>::value, + integral_constant, + is_placeholder::type> +> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; +#endif + +namespace placeholders +{ + +template struct __ph {}; + +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) +_LIBCPP_FUNC_VIS extern const __ph<1> _1; +_LIBCPP_FUNC_VIS extern const __ph<2> _2; +_LIBCPP_FUNC_VIS extern const __ph<3> _3; +_LIBCPP_FUNC_VIS extern const __ph<4> _4; +_LIBCPP_FUNC_VIS extern const __ph<5> _5; +_LIBCPP_FUNC_VIS extern const __ph<6> _6; +_LIBCPP_FUNC_VIS extern const __ph<7> _7; +_LIBCPP_FUNC_VIS extern const __ph<8> _8; +_LIBCPP_FUNC_VIS extern const __ph<9> _9; +_LIBCPP_FUNC_VIS extern const __ph<10> _10; +#else +/* inline */ constexpr __ph<1> _1{}; +/* inline */ constexpr __ph<2> _2{}; +/* inline */ constexpr __ph<3> _3{}; +/* inline */ constexpr __ph<4> _4{}; +/* inline */ constexpr __ph<5> _5{}; +/* inline */ constexpr __ph<6> _6{}; +/* inline */ constexpr __ph<7> _7{}; +/* inline */ constexpr __ph<8> _8{}; +/* inline */ constexpr __ph<9> _9{}; +/* inline */ constexpr __ph<10> _10{}; +#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) + +} // namespace placeholders + +template +struct is_placeholder > + : public integral_constant {}; + + +#ifndef _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp& +__mu(reference_wrapper<_Tp> __t, _Uj&) +{ + return __t.get(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __invoke_of<_Ti&, _Uj...>::type +__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) +{ + return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_if_t +< + is_bind_expression<_Ti>::value, + __invoke_of<_Ti&, _Uj...> +>::type +__mu(_Ti& __ti, tuple<_Uj...>& __uj) +{ + typedef typename __make_tuple_indices::type __indices; + return _VSTD::__mu_expand(__ti, __uj, __indices()); +} + +template +struct __mu_return2 {}; + +template +struct __mu_return2 +{ + typedef typename tuple_element::value - 1, _Uj>::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + 0 < is_placeholder<_Ti>::value, + typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type +>::type +__mu(_Ti&, _Uj& __uj) +{ + const size_t _Indx = is_placeholder<_Ti>::value - 1; + return _VSTD::forward::type>(_VSTD::get<_Indx>(__uj)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + !is_bind_expression<_Ti>::value && + is_placeholder<_Ti>::value == 0 && + !__is_reference_wrapper<_Ti>::value, + _Ti& +>::type +__mu(_Ti& __ti, _Uj&) +{ + return __ti; +} + +template +struct __mu_return_impl; + +template +struct __mu_return_invokable // false +{ + typedef __nat type; +}; + +template +struct __mu_return_invokable +{ + typedef typename __invoke_of<_Ti&, _Uj...>::type type; +}; + +template +struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > + : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> +{ +}; + +template +struct __mu_return_impl<_Ti, false, false, true, _TupleUj> +{ + typedef typename tuple_element::value - 1, + _TupleUj>::type&& type; +}; + +template +struct __mu_return_impl<_Ti, true, false, false, _TupleUj> +{ + typedef typename _Ti::type& type; +}; + +template +struct __mu_return_impl<_Ti, false, false, false, _TupleUj> +{ + typedef _Ti& type; +}; + +template +struct __mu_return + : public __mu_return_impl<_Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && + is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> +{ +}; + +template +struct __is_valid_bind_return +{ + static const bool value = false; +}; + +template +struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +}; + +template +struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> +{ + static const bool value = __invokable<_Fp, + typename __mu_return::type...>::value; +}; + +template ::value> +struct __bind_return; + +template +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> +{ + typedef typename __invoke_of + < + _Fp&, + typename __mu_return + < + const _BoundArgs, + _TupleUj + >::type... + >::type type; +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __bind_return<_Fp, _BoundArgs, _Args>::type +__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, + _Args&& __args) +{ + return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...); +} + +template +class __bind +#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public __weak_result_type::type> +#endif +{ +protected: + typedef typename decay<_Fp>::type _Fd; + typedef tuple::type...> _Td; +private: + _Fd __f_; + _Td __bound_args_; + + typedef typename __make_tuple_indices::type __indices; +public: + template ::value && + !is_same::type, + __bind>::value + >::type> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + explicit __bind(_Gp&& __f, _BA&& ...__bound_args) + : __f_(_VSTD::forward<_Gp>(__f)), + __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + operator()(_Args&& ...__args) + { + return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename __bind_return >::type + operator()(_Args&& ...__args) const + { + return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), + tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); + } +}; + +template +struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; + +template +class __bind_r + : public __bind<_Fp, _BoundArgs...> +{ + typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; +public: + typedef _Rp result_type; + + + template ::value && + !is_same::type, + __bind_r>::value + >::type> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) + : base(_VSTD::forward<_Gp>(__f), + _VSTD::forward<_BA>(__bound_args)...) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename enable_if + < + is_convertible >::type, + result_type>::value || is_void<_Rp>::value, + result_type + >::type + operator()(_Args&& ...__args) const + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); + } +}; + +template +struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +__bind<_Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind<_Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +__bind_r<_Rp, _Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) +{ + typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; + return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_H diff --git a/include/__functional/bind_back.h b/include/__functional/bind_back.h new file mode 100644 index 000000000..a0089e1fb --- /dev/null +++ b/include/__functional/bind_back.h @@ -0,0 +1,65 @@ +// -*- 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_BIND_BACK_H +#define _LIBCPP___FUNCTIONAL_BIND_BACK_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include <__utility/integer_sequence.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template > +struct __bind_back_op; + +template +struct __bind_back_op<_NBound, index_sequence<_Ip...>> { + template + _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 +struct __bind_back_t : __perfect_forward<__bind_back_op>, _Fn, _BoundArgs> { + using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; +}; + +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) + noexcept(noexcept(__bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))) + -> decltype( __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))) + { return __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_BACK_H diff --git a/include/__functional/bind_front.h b/include/__functional/bind_front.h new file mode 100644 index 000000000..31397ec54 --- /dev/null +++ b/include/__functional/bind_front.h @@ -0,0 +1,58 @@ +// -*- 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_BIND_FRONT_H +#define _LIBCPP___FUNCTIONAL_BIND_FRONT_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct __bind_front_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Args&& ...__args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { + using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; +}; + +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { + return __bind_front_t, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H diff --git a/include/__functional/binder1st.h b/include/__functional/binder1st.h new file mode 100644 index 000000000..5dd8f5cf0 --- /dev/null +++ b/include/__functional/binder1st.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___FUNCTIONAL_BINDER1ST_H +#define _LIBCPP___FUNCTIONAL_BINDER1ST_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st + : public unary_function +{ +protected: + __Operation op; + typename __Operation::first_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x, + const typename __Operation::first_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (typename __Operation::second_argument_type& __x) const + {return op(value, __x);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::second_argument_type& __x) const + {return op(value, __x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +binder1st<__Operation> +bind1st(const __Operation& __op, const _Tp& __x) + {return binder1st<__Operation>(__op, __x);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINDER1ST_H diff --git a/include/__functional/binder2nd.h b/include/__functional/binder2nd.h new file mode 100644 index 000000000..3ed5f5bf4 --- /dev/null +++ b/include/__functional/binder2nd.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___FUNCTIONAL_BINDER2ND_H +#define _LIBCPP___FUNCTIONAL_BINDER2ND_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd + : public unary_function +{ +protected: + __Operation op; + typename __Operation::second_argument_type value; +public: + _LIBCPP_INLINE_VISIBILITY + binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + ( typename __Operation::first_argument_type& __x) const + {return op(__x, value);} + _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() + (const typename __Operation::first_argument_type& __x) const + {return op(__x, value);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +binder2nd<__Operation> +bind2nd(const __Operation& __op, const _Tp& __x) + {return binder2nd<__Operation>(__op, __x);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BINDER2ND_H diff --git a/include/__functional/compose.h b/include/__functional/compose.h new file mode 100644 index 000000000..d9d75875c --- /dev/null +++ b/include/__functional/compose.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___FUNCTIONAL_COMPOSE_H +#define _LIBCPP___FUNCTIONAL_COMPOSE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct __compose_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...))) + { return _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)); } +}; + +template +struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> { + using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) + noexcept(noexcept(__compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))) + -> decltype( __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))) + { return __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_COMPOSE_H diff --git a/include/__functional/default_searcher.h b/include/__functional/default_searcher.h new file mode 100644 index 000000000..1acbc1883 --- /dev/null +++ b/include/__functional/default_searcher.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___FUNCTIONAL_DEFAULT_SEARCHER_H +#define _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H + +#include <__algorithm/search.h> +#include <__config> +#include <__functional/operations.h> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +// default searcher +template> +class _LIBCPP_TEMPLATE_VIS default_searcher { +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + default_searcher(_ForwardIterator __f, _ForwardIterator __l, + _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + pair<_ForwardIterator2, _ForwardIterator2> + operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + { + return _VSTD::__search(__f, __l, __first_, __last_, __pred_, + typename iterator_traits<_ForwardIterator>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()); + } + +private: + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; + }; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H diff --git a/include/__functional/function.h b/include/__functional/function.h new file mode 100644 index 000000000..6bb7eb7e8 --- /dev/null +++ b/include/__functional/function.h @@ -0,0 +1,2810 @@ +// -*- 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_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_FUNCTION_H + +#include <__config> +#include <__debug> +#include <__functional/binary_function.h> +#include <__functional/invoke.h> +#include <__functional/unary_function.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/allocator_traits.h> +#include <__memory/compressed_pair.h> +#include <__memory/shared_ptr.h> +#include +#include // TODO: replace with <__memory/__builtin_new_allocator.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// bad_function_call + +class _LIBCPP_EXCEPTION_ABI bad_function_call + : public exception +{ +public: +// Note that when a key function is not used, every translation unit that uses +// bad_function_call will end up containing a weak definition of the vtable and +// typeinfo. +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION + virtual ~bad_function_call() _NOEXCEPT; +#else + virtual ~bad_function_call() _NOEXCEPT {} +#endif + +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE + virtual const char* what() const _NOEXCEPT; +#endif +}; + +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +void __throw_bad_function_call() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_function_call(); +#else + _VSTD::abort(); +#endif +} + +#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ + __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) +#else +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ +#endif + +template class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined + +namespace __function +{ + +template +struct __maybe_derive_from_unary_function +{ +}; + +template +struct __maybe_derive_from_unary_function<_Rp(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __maybe_derive_from_binary_function +{ +}; + +template +struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp const&) { return true; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp* __ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(function<_Fp> const& __f) { return !!__f; } + +#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Rp (^__p)(_Args...)) { return __p; } +#endif + +} // namespace __function + +#ifndef _LIBCPP_CXX03_LANG + +namespace __function { + +// __alloc_func holds a functor and an allocator. + +template class __alloc_func; +template +class __default_alloc_func; + +template +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Ap> __f_; + + public: + typedef _LIBCPP_NODEBUG _Fp _Target; + typedef _LIBCPP_NODEBUG _Ap _Alloc; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_.first(); } + + // WIN32 APIs may define __allocator, so use __get_allocator instead. + _LIBCPP_INLINE_VISIBILITY + const _Alloc& __get_allocator() const { return __f_.second(); } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple()) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(__a)) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), + _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __alloc_func* __clone() const + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef + typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type + _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } + + static void __destroy_and_delete(__alloc_func* __f) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type + _FunAlloc; + _FunAlloc __a(__f->__get_allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } +}; + +template +class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { + _Fp __f_; + +public: + typedef _LIBCPP_NODEBUG _Fp _Target; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_; } + + _LIBCPP_INLINE_VISIBILITY + explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __default_alloc_func* __clone() const { + __builtin_new_allocator::__holder_t __hold = + __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); + __default_alloc_func* __res = + ::new ((void*)__hold.get()) __default_alloc_func(__f_); + (void)__hold.release(); + return __res; + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~_Target(); } + + static void __destroy_and_delete(__default_alloc_func* __f) { + __f->destroy(); + __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); + } +}; + +// __base provides an abstract interface for copyable functors. + +template class _LIBCPP_TEMPLATE_VIS __base; + +template +class __base<_Rp(_ArgTypes...)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + _LIBCPP_INLINE_VISIBILITY __base() {} + _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() _NOEXCEPT = 0; + virtual void destroy_deallocate() _NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&& ...) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT = 0; + virtual const std::type_info& target_type() const _NOEXCEPT = 0; +#endif // _LIBCPP_NO_RTTI +}; + +// __func implements __base for a given functor type. + +template class __func; + +template +class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f) + : __f_(_VSTD::move(__f)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, const _Alloc& __a) + : __f_(__f, __a) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f, _Alloc&& __a) + : __f_(__f, _VSTD::move(__a)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f, _Alloc&& __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + + virtual __base<_Rp(_ArgTypes...)>* __clone() const; + virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + virtual void destroy() _NOEXCEPT; + virtual void destroy_deallocate() _NOEXCEPT; + virtual _Rp operator()(_ArgTypes&&... __arg); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT; + virtual const std::type_info& target_type() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_ArgTypes...)>* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.__get_allocator()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const +{ + ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT +{ + __f_.destroy(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.__get_allocator()); + __f_.destroy(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) +{ + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT +{ + if (__ti == typeid(_Fp)) + return _VSTD::addressof(__f_.__target()); + return nullptr; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +// __value_func creates a value-type from a __func. + +template class __value_func; + +template class __value_func<_Rp(_ArgTypes...)> +{ + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; + + _LIBCPP_NO_CFI static __func* __as_base(void* p) + { + return reinterpret_cast<__func*>(p); + } + + public: + _LIBCPP_INLINE_VISIBILITY + __value_func() _NOEXCEPT : __f_(nullptr) {} + + template + _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) + : __f_(nullptr) + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && + is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) + { + __f_ = + ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } + } + } + + template ::type, __value_func>::value>::type> + _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) + : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} + + _LIBCPP_INLINE_VISIBILITY + __value_func(const __value_func& __f) + { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(__value_func&& __f) _NOEXCEPT + { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__value_func() + { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(__value_func&& __f) + { + *this = nullptr; + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = nullptr; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(nullptr_t) + { + __func* __f = __f_; + __f_ = nullptr; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + if (__f_ == nullptr) + __throw_bad_function_call(); + return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__value_func& __f) _NOEXCEPT + { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = nullptr; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = nullptr; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f_ == &__buf_) + { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } + else + _VSTD::swap(__f_, __f.__f_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + if (__f_ == nullptr) + return typeid(void); + return __f_->target_type(); + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__f_ == nullptr) + return nullptr; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +#endif // _LIBCPP_NO_RTTI +}; + +// Storage for a functor object, to be used with __policy to manage copy and +// destruction. +union __policy_storage +{ + mutable char __small[sizeof(void*) * 2]; + void* __large; +}; + +// True if _Fun can safely be held in __policy_storage.__small. +template +struct __use_small_storage + : public integral_constant< + bool, sizeof(_Fun) <= sizeof(__policy_storage) && + _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && + is_trivially_copy_constructible<_Fun>::value && + is_trivially_destructible<_Fun>::value> {}; + +// Policy contains information about how to copy, destroy, and move the +// underlying functor. You can think of it as a vtable of sorts. +struct __policy +{ + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); + + // True if this is the null policy (no value). + const bool __is_null; + + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; + + // Returns a pointer to a static policy object suitable for the functor + // type. + template + _LIBCPP_INLINE_VISIBILITY static const __policy* __create() + { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } + + _LIBCPP_INLINE_VISIBILITY + static const __policy* __create_empty() + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, + true, +#ifndef _LIBCPP_NO_RTTI + &typeid(void) +#else + nullptr +#endif + }; + return &__policy_; + } + + private: + template static void* __large_clone(const void* __s) + { + const _Fun* __f = static_cast(__s); + return __f->__clone(); + } + + template + static void __large_destroy(void* __s) { + _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ false_type) { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + &__large_clone<_Fun>, &__large_destroy<_Fun>, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } + + template + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ true_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + nullptr, nullptr, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } +}; + +// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is +// faster for types that can be passed in registers. +template +using __fast_forward = + typename conditional::value, _Tp, _Tp&&>::type; + +// __policy_invoker calls an instance of __alloc_func held in __policy_storage. + +template struct __policy_invoker; + +template +struct __policy_invoker<_Rp(_ArgTypes...)> +{ + typedef _Rp (*__Call)(const __policy_storage*, + __fast_forward<_ArgTypes>...); + + __Call __call_; + + // Creates an invoker that throws bad_function_call. + _LIBCPP_INLINE_VISIBILITY + __policy_invoker() : __call_(&__call_empty) {} + + // Creates an invoker that calls the given instance of __func. + template + _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() + { + return __policy_invoker(&__call_impl<_Fun>); + } + + private: + _LIBCPP_INLINE_VISIBILITY + explicit __policy_invoker(__Call __c) : __call_(__c) {} + + static _Rp __call_empty(const __policy_storage*, + __fast_forward<_ArgTypes>...) + { + __throw_bad_function_call(); + } + + template + static _Rp __call_impl(const __policy_storage* __buf, + __fast_forward<_ArgTypes>... __args) + { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value + ? &__buf->__small + : __buf->__large); + return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); + } +}; + +// __policy_func uses a __policy and __policy_invoker to create a type-erased, +// copyable functor. + +template class __policy_func; + +template class __policy_func<_Rp(_ArgTypes...)> +{ + // Inline storage for small objects. + __policy_storage __buf_; + + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; + + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; + + public: + _LIBCPP_INLINE_VISIBILITY + __policy_func() : __policy_(__policy::__create_empty()) {} + + template + _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) + : __policy_(__policy::__create_empty()) + { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) + { + ::new ((void*)&__buf_.__small) + _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) + _Fun(_VSTD::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); + } + } + } + + template ::type, __policy_func>::value>::type> + _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) + : __policy_(__policy::__create_empty()) { + typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; + + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); + } else { + __builtin_new_allocator::__holder_t __hold = + __builtin_new_allocator::__allocate_type<_Fun>(1); + __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); + (void)__hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__destroy) + { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__policy_func() + { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(__policy_func&& __f) + { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(nullptr_t) + { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + return __invoker_.__call_(_VSTD::addressof(__buf_), + _VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__policy_func& __f) + { + _VSTD::swap(__invoker_, __f.__invoker_); + _VSTD::swap(__policy_, __f.__policy_); + _VSTD::swap(__buf_, __f.__buf_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT + { + return !__policy_->__is_null; + } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + return *__policy_->__type_info; + } + + template + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast(__buf_.__large); + else + return reinterpret_cast(&__buf_.__small); + } +#endif // _LIBCPP_NO_RTTI +}; + +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) + +extern "C" void *_Block_copy(const void *); +extern "C" void _Block_release(const void *); + +template +class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + typedef _Rp1(^__block_type)(_ArgTypes1...); + __block_type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type const& __f) + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) + { } + + // [TODO] add && to save on a retain + + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type __f, const _Alloc& /* unused */) + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) + { } + + virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } + + virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new ((void*)__p) __func(__f_); + } + + virtual void destroy() _NOEXCEPT { + if (__f_) + _Block_release(__f_); + __f_ = 0; + } + + virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } + + virtual _Rp operator()(_ArgTypes&& ... __arg) { + return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + virtual const std::type_info& target_type() const _NOEXCEPT { + return typeid(__func::__block_type); + } +#endif // _LIBCPP_NO_RTTI +}; + +#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC + +} // namespace __function + +template +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; +#else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +#endif + + __func __f_; + + template , function>, + __invokable<_Fp, _ArgTypes...> + >::value> + struct __callable; + template + struct __callable<_Fp, true> + { + static const bool value = is_void<_Rp>::value || + __is_core_convertible::type, + _Rp>::value; + }; + template + struct __callable<_Fp, false> + { + static const bool value = false; + }; + + template + using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; +public: + typedef _Rp result_type; + + // construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY + function() _NOEXCEPT { } + _LIBCPP_INLINE_VISIBILITY + function(nullptr_t) _NOEXCEPT {} + function(const function&); + function(function&&) _NOEXCEPT; + template> + function(_Fp); + +#if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc&, function&&); + template> + function(allocator_arg_t, const _Alloc& __a, _Fp __f); +#endif + + function& operator=(const function&); + function& operator=(function&&) _NOEXCEPT; + function& operator=(nullptr_t) _NOEXCEPT; + template::type>> + function& operator=(_Fp&&); + + ~function(); + + // function modifiers: + void swap(function&) _NOEXCEPT; + +#if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp&& __f, const _Alloc& __a) + {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} +#endif + + // function capacity: + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT { + return static_cast(__f_); + } + + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; +public: + // function invocation: + _Rp operator()(_ArgTypes...) const; + +#ifndef _LIBCPP_NO_RTTI + // function target access: + const std::type_info& target_type() const _NOEXCEPT; + template _Tp* target() _NOEXCEPT; + template const _Tp* target() const _NOEXCEPT; +#endif // _LIBCPP_NO_RTTI +}; + +#if _LIBCPP_STD_VER >= 17 +template +function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; + +template +struct __strip_signature; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; + +template::type> +function(_Fp) -> function<_Stripped>; +#endif // _LIBCPP_STD_VER >= 17 + +template +function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + const function& __f) : __f_(__f.__f_) {} +#endif + +template +function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT + : __f_(_VSTD::move(__f.__f_)) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, + function&& __f) + : __f_(_VSTD::move(__f.__f_)) {} +#endif + +template +template +function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} + +#if _LIBCPP_STD_VER <= 14 +template +template +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, + _Fp __f) + : __f_(_VSTD::move(__f), __a) {} +#endif + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(const function& __f) +{ + function(__f).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT +{ + __f_ = _VSTD::move(__f.__f_); + return *this; +} + +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT +{ + __f_ = nullptr; + return *this; +} + +template +template +function<_Rp(_ArgTypes...)>& +function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) +{ + function(_VSTD::forward<_Fp>(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_ArgTypes...)>::~function() {} + +template +void +function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT +{ + __f_.swap(__f.__f_); +} + +template +_Rp +function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const +{ + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT +{ + return __f_.target_type(); +} + +template +template +_Tp* +function<_Rp(_ArgTypes...)>::target() _NOEXCEPT +{ + return (_Tp*)(__f_.template target<_Tp>()); +} + +template +template +const _Tp* +function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT +{ + return __f_.template target<_Tp>(); +} + +#endif // _LIBCPP_NO_RTTI + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT +{return __x.swap(__y);} + +#else // _LIBCPP_CXX03_LANG + +namespace __function { + +template class __base; + +template +class __base<_Rp()> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()() = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0, _A1)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0, _A1) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template +class __base<_Rp(_A0, _A1, _A2)> +{ + __base(const __base&); + __base& operator=(const __base&); +public: + __base() {} + virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() = 0; + virtual void destroy_deallocate() = 0; + virtual _Rp operator()(_A0, _A1, _A2) = 0; +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const = 0; + virtual const std::type_info& target_type() const = 0; +#endif // _LIBCPP_NO_RTTI +}; + +template class __func; + +template +class __func<_Fp, _Alloc, _Rp()> + : public __base<_Rp()> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} + explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp()>* __clone() const; + virtual void __clone(__base<_Rp()>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp()>* +__func<_Fp, _Alloc, _Rp()>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const +{ + ::new ((void*)__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp()>::operator()() +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first()); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return _VSTD::addressof(__f_.first()); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp()>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0)> + : public __base<_Rp(_A0)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0)>* __clone() const; + virtual void __clone(__base<_Rp(_A0)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0)>* +__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const +{ + ::new ((void*)__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0, _A1)> + : public __base<_Rp(_A0, _A1)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0, _A1)>* __clone() const; + virtual void __clone(__base<_Rp(_A0, _A1)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0, _A1); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0, _A1)>* +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const +{ + ::new ((void*)__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0, __a1); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +template +class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> + : public __base<_Rp(_A0, _A1, _A2)> +{ + __compressed_pair<_Fp, _Alloc> __f_; +public: + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; + virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; + virtual void destroy(); + virtual void destroy_deallocate(); + virtual _Rp operator()(_A0, _A1, _A2); +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(const type_info&) const; + virtual const std::type_info& target_type() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +__base<_Rp(_A0, _A1, _A2)>* +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); + return __hold.release(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const +{ + ::new ((void*)__p) __func(__f_.first(), __f_.second()); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() +{ + __f_.~__compressed_pair<_Fp, _Alloc>(); +} + +template +void +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() +{ + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + _Ap __a(__f_.second()); + __f_.~__compressed_pair<_Fp, _Alloc>(); + __a.deallocate(this, 1); +} + +template +_Rp +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) +{ + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), __a0, __a1, __a2); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const void* +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const +{ + if (__ti == typeid(_Fp)) + return &__f_.first(); + return (const void*)0; +} + +template +const std::type_info& +__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const +{ + return typeid(_Fp); +} + +#endif // _LIBCPP_NO_RTTI + +} // namespace __function + +template +class _LIBCPP_TEMPLATE_VIS function<_Rp()> +{ + typedef __function::__base<_Rp()> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} + + template + bool operator==(const function<_R2()>&) const = delete; + template + bool operator!=(const function<_R2()>&) const = delete; + + // 20.7.16.2.4, function invocation: + _Rp operator()() const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp()>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp()>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp()>& +function<_Rp()>::operator=(const function& __f) +{ + if (__f) + function(__f).swap(*this); + else + *this = nullptr; + return *this; +} + +template +function<_Rp()>& +function<_Rp()>::operator=(nullptr_t) +{ + __base* __t = __f_; + __f_ = 0; + if (__t == (__base*)&__buf_) + __t->destroy(); + else if (__t) + __t->destroy_deallocate(); + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp()>& +>::type +function<_Rp()>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp()>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp()>::swap(function& __f) +{ + if (_VSTD::addressof(__f) == this) + return; + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp()>::operator()() const +{ + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp()>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp()>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*) const_cast(__f_->target(typeid(_Tp))); +} + +template +template +const _Tp* +function<_Rp()>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> + : public unary_function<_A0, _Rp> +{ + typedef __function::__base<_Rp(_A0)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} + + template + bool operator==(const function<_R2(_B0)>&) const = delete; + template + bool operator!=(const function<_R2(_B0)>&) const = delete; + + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0)>& +function<_Rp(_A0)>::operator=(const function& __f) +{ + if (__f) + function(__f).swap(*this); + else + *this = nullptr; + return *this; +} + +template +function<_Rp(_A0)>& +function<_Rp(_A0)>::operator=(nullptr_t) +{ + __base* __t = __f_; + __f_ = 0; + if (__t == (__base*)&__buf_) + __t->destroy(); + else if (__t) + __t->destroy_deallocate(); + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0)>& +>::type +function<_Rp(_A0)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0)>::swap(function& __f) +{ + if (_VSTD::addressof(__f) == this) + return; + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0)>::operator()(_A0 __a0) const +{ + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(__a0); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*) const_cast(__f_->target(typeid(_Tp))); +} + +template +template +const _Tp* +function<_Rp(_A0)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> + : public binary_function<_A0, _A1, _Rp> +{ + typedef __function::__base<_Rp(_A0, _A1)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} + + template + bool operator==(const function<_R2(_B0, _B1)>&) const = delete; + template + bool operator!=(const function<_R2(_B0, _B1)>&) const = delete; + + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0, _A1) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0, _A1)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0, _A1)>& +function<_Rp(_A0, _A1)>::operator=(const function& __f) +{ + if (__f) + function(__f).swap(*this); + else + *this = nullptr; + return *this; +} + +template +function<_Rp(_A0, _A1)>& +function<_Rp(_A0, _A1)>::operator=(nullptr_t) +{ + __base* __t = __f_; + __f_ = 0; + if (__t == (__base*)&__buf_) + __t->destroy(); + else if (__t) + __t->destroy_deallocate(); + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0, _A1)>& +>::type +function<_Rp(_A0, _A1)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0, _A1)>::swap(function& __f) +{ + if (_VSTD::addressof(__f) == this) + return; + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const +{ + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(__a0, __a1); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0, _A1)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0, _A1)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*) const_cast(__f_->target(typeid(_Tp))); +} + +template +template +const _Tp* +function<_Rp(_A0, _A1)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> +{ + typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; + aligned_storage<3*sizeof(void*)>::type __buf_; + __base* __f_; + +public: + typedef _Rp result_type; + + // 20.7.16.2.1, construct/copy/destroy: + _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} + _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} + function(const function&); + template + function(_Fp, + typename enable_if::value>::type* = 0); + + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&) : __f_(0) {} + template + _LIBCPP_INLINE_VISIBILITY + function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} + template + function(allocator_arg_t, const _Alloc&, const function&); + template + function(allocator_arg_t, const _Alloc& __a, _Fp __f, + typename enable_if::value>::type* = 0); + + function& operator=(const function&); + function& operator=(nullptr_t); + template + typename enable_if + < + !is_integral<_Fp>::value, + function& + >::type + operator=(_Fp); + + ~function(); + + // 20.7.16.2.2, function modifiers: + void swap(function&); + template + _LIBCPP_INLINE_VISIBILITY + void assign(_Fp __f, const _Alloc& __a) + {function(allocator_arg, __a, __f).swap(*this);} + + // 20.7.16.2.3, function capacity: + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} + + template + bool operator==(const function<_R2(_B0, _B1, _B2)>&) const = delete; + template + bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const = delete; + + // 20.7.16.2.4, function invocation: + _Rp operator()(_A0, _A1, _A2) const; + +#ifndef _LIBCPP_NO_RTTI + // 20.7.16.2.5, function target access: + const std::type_info& target_type() const; + template _Tp* target(); + template const _Tp* target() const; +#endif // _LIBCPP_NO_RTTI +}; + +template +function<_Rp(_A0, _A1, _A2)>::function(const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, + const function& __f) +{ + if (__f.__f_ == 0) + __f_ = 0; + else if (__f.__f_ == (const __base*)&__f.__buf_) + { + __f_ = (__base*)&__buf_; + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f); + } + else + { + typedef allocator<_FF> _Ap; + _Ap __a; + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); + __f_ = __hold.release(); + } + } +} + +template +template +function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, + typename enable_if::value>::type*) + : __f_(0) +{ + typedef allocator_traits<_Alloc> __alloc_traits; + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; + if (sizeof(_FF) <= sizeof(__buf_)) + { + __f_ = (__base*)&__buf_; + ::new ((void*)__f_) _FF(__f, __a0); + } + else + { + typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; + _Ap __a(__a0); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); + __f_ = __hold.release(); + } + } +} + +template +function<_Rp(_A0, _A1, _A2)>& +function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) +{ + if (__f) + function(__f).swap(*this); + else + *this = nullptr; + return *this; +} + +template +function<_Rp(_A0, _A1, _A2)>& +function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) +{ + __base* __t = __f_; + __f_ = 0; + if (__t == (__base*)&__buf_) + __t->destroy(); + else if (__t) + __t->destroy_deallocate(); + return *this; +} + +template +template +typename enable_if +< + !is_integral<_Fp>::value, + function<_Rp(_A0, _A1, _A2)>& +>::type +function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) +{ + function(_VSTD::move(__f)).swap(*this); + return *this; +} + +template +function<_Rp(_A0, _A1, _A2)>::~function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template +void +function<_Rp(_A0, _A1, _A2)>::swap(function& __f) +{ + if (_VSTD::addressof(__f) == this) + return; + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage::type __tempbuf; + __base* __t = (__base*)&__tempbuf; + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = (__base*)&__buf_; + __t->__clone((__base*)&__f.__buf_); + __t->destroy(); + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f_ == (__base*)&__buf_) + { + __f_->__clone((__base*)&__f.__buf_); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = (__base*)&__f.__buf_; + } + else if (__f.__f_ == (__base*)&__f.__buf_) + { + __f.__f_->__clone((__base*)&__buf_); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = (__base*)&__buf_; + } + else + _VSTD::swap(__f_, __f.__f_); +} + +template +_Rp +function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const +{ + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(__a0, __a1, __a2); +} + +#ifndef _LIBCPP_NO_RTTI + +template +const std::type_info& +function<_Rp(_A0, _A1, _A2)>::target_type() const +{ + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); +} + +template +template +_Tp* +function<_Rp(_A0, _A1, _A2)>::target() +{ + if (__f_ == 0) + return (_Tp*)0; + return (_Tp*) const_cast(__f_->target(typeid(_Tp))); +} + +template +template +const _Tp* +function<_Rp(_A0, _A1, _A2)>::target() const +{ + if (__f_ == 0) + return (const _Tp*)0; + return (const _Tp*)__f_->target(typeid(_Tp)); +} + +#endif // _LIBCPP_NO_RTTI + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} + +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(function<_Fp>& __x, function<_Fp>& __y) +{return __x.swap(__y);} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H diff --git a/include/__functional/hash.h b/include/__functional/hash.h new file mode 100644 index 000000000..de0c161f4 --- /dev/null +++ b/include/__functional/hash.h @@ -0,0 +1,870 @@ +//===----------------------------------------------------------------------===// +// +// 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_HASH_H +#define _LIBCPP___FUNCTIONAL_HASH_H + +#include <__config> +#include <__functional/unary_function.h> +#include <__tuple> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <__utility/swap.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY +_Size +__loadword(const void* __p) +{ + _Size __r; + _VSTD::memcpy(&__r, __p, sizeof(__r)); + return __r; +} + +// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t +// is 64 bits. This is because cityhash64 uses 64bit x 64bit +// multiplication, which can be very slow on 32-bit systems. +template +struct __murmur2_or_cityhash; + +template +struct __murmur2_or_cityhash<_Size, 32> +{ + inline _Size operator()(const void* __key, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; +}; + +// murmur2 +template +_Size +__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) +{ + const _Size __m = 0x5bd1e995; + const _Size __r = 24; + _Size __h = __len; + const unsigned char* __data = static_cast(__key); + for (; __len >= 4; __data += 4, __len -= 4) + { + _Size __k = __loadword<_Size>(__data); + __k *= __m; + __k ^= __k >> __r; + __k *= __m; + __h *= __m; + __h ^= __k; + } + switch (__len) + { + case 3: + __h ^= static_cast<_Size>(__data[2] << 16); + _LIBCPP_FALLTHROUGH(); + case 2: + __h ^= static_cast<_Size>(__data[1] << 8); + _LIBCPP_FALLTHROUGH(); + case 1: + __h ^= __data[0]; + __h *= __m; + } + __h ^= __h >> 13; + __h *= __m; + __h ^= __h >> 15; + return __h; +} + +template +struct __murmur2_or_cityhash<_Size, 64> +{ + inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; + + private: + // Some primes between 2^63 and 2^64. + static const _Size __k0 = 0xc3a5c85c97cb3127ULL; + static const _Size __k1 = 0xb492b66fbe98f273ULL; + static const _Size __k2 = 0x9ae16a3b2f90404fULL; + static const _Size __k3 = 0xc949d7c7509e6557ULL; + + static _Size __rotate(_Size __val, int __shift) { + return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); + } + + static _Size __rotate_by_at_least_1(_Size __val, int __shift) { + return (__val >> __shift) | (__val << (64 - __shift)); + } + + static _Size __shift_mix(_Size __val) { + return __val ^ (__val >> 47); + } + + static _Size __hash_len_16(_Size __u, _Size __v) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + const _Size __mul = 0x9ddfea08eb382d69ULL; + _Size __a = (__u ^ __v) * __mul; + __a ^= (__a >> 47); + _Size __b = (__v ^ __a) * __mul; + __b ^= (__b >> 47); + __b *= __mul; + return __b; + } + + static _Size __hash_len_0_to_16(const char* __s, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + if (__len > 8) { + const _Size __a = __loadword<_Size>(__s); + const _Size __b = __loadword<_Size>(__s + __len - 8); + return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b; + } + if (__len >= 4) { + const uint32_t __a = __loadword(__s); + const uint32_t __b = __loadword(__s + __len - 4); + return __hash_len_16(__len + (__a << 3), __b); + } + if (__len > 0) { + const unsigned char __a = static_cast(__s[0]); + const unsigned char __b = static_cast(__s[__len >> 1]); + const unsigned char __c = static_cast(__s[__len - 1]); + const uint32_t __y = static_cast(__a) + + (static_cast(__b) << 8); + const uint32_t __z = __len + (static_cast(__c) << 2); + return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; + } + return __k2; + } + + static _Size __hash_len_17_to_32(const char *__s, _Size __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + const _Size __a = __loadword<_Size>(__s) * __k1; + const _Size __b = __loadword<_Size>(__s + 8); + const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2; + const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0; + return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, + __a + __rotate(__b ^ __k3, 20) - __c + __len); + } + + // Return a 16-byte hash for 48 bytes. Quick and dirty. + // Callers do best to use "random-looking" values for a and b. + static pair<_Size, _Size> __weak_hash_len_32_with_seeds( + _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + __a += __w; + __b = __rotate(__b + __a + __z, 21); + const _Size __c = __a; + __a += __x; + __a += __y; + __b += __rotate(__a, 44); + return pair<_Size, _Size>(__a + __z, __b + __c); + } + + // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. + static pair<_Size, _Size> __weak_hash_len_32_with_seeds( + const char* __s, _Size __a, _Size __b) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s), + __loadword<_Size>(__s + 8), + __loadword<_Size>(__s + 16), + __loadword<_Size>(__s + 24), + __a, + __b); + } + + // Return an 8-byte hash for 33 to 64 bytes. + static _Size __hash_len_33_to_64(const char *__s, size_t __len) + _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK + { + _Size __z = __loadword<_Size>(__s + 24); + _Size __a = __loadword<_Size>(__s) + + (__len + __loadword<_Size>(__s + __len - 16)) * __k0; + _Size __b = __rotate(__a + __z, 52); + _Size __c = __rotate(__a, 37); + __a += __loadword<_Size>(__s + 8); + __c += __rotate(__a, 7); + __a += __loadword<_Size>(__s + 16); + _Size __vf = __a + __z; + _Size __vs = __b + __rotate(__a, 31) + __c; + __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32); + __z += __loadword<_Size>(__s + __len - 8); + __b = __rotate(__a + __z, 52); + __c = __rotate(__a, 37); + __a += __loadword<_Size>(__s + __len - 24); + __c += __rotate(__a, 7); + __a += __loadword<_Size>(__s + __len - 16); + _Size __wf = __a + __z; + _Size __ws = __b + __rotate(__a, 31) + __c; + _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); + return __shift_mix(__r * __k0 + __vs) * __k2; + } +}; + +// cityhash64 +template +_Size +__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) +{ + const char* __s = static_cast(__key); + if (__len <= 32) { + if (__len <= 16) { + return __hash_len_0_to_16(__s, __len); + } else { + return __hash_len_17_to_32(__s, __len); + } + } else if (__len <= 64) { + return __hash_len_33_to_64(__s, __len); + } + + // For strings over 64 bytes we hash the end first, and then as we + // loop we keep 56 bytes of state: v, w, x, y, and z. + _Size __x = __loadword<_Size>(__s + __len - 40); + _Size __y = __loadword<_Size>(__s + __len - 16) + + __loadword<_Size>(__s + __len - 56); + _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len, + __loadword<_Size>(__s + __len - 24)); + pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); + pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); + __x = __x * __k1 + __loadword<_Size>(__s); + + // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. + __len = (__len - 1) & ~static_cast<_Size>(63); + do { + __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1; + __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1; + __x ^= __w.second; + __y += __v.first + __loadword<_Size>(__s + 40); + __z = __rotate(__z + __w.first, 33) * __k1; + __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); + __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, + __y + __loadword<_Size>(__s + 16)); + _VSTD::swap(__z, __x); + __s += 64; + __len -= 64; + } while (__len != 0); + return __hash_len_16( + __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, + __hash_len_16(__v.second, __w.second) + __x); +} + +template +struct __scalar_hash; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __scalar_hash<_Tp, 0> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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 + { + union + { + _Tp __t; + size_t __a; + } __u; + __u.__a = 0; + __u.__t = __v; + return __u.__a; + } +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __scalar_hash<_Tp, 1> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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 + { + union + { + _Tp __t; + size_t __a; + } __u; + __u.__t = __v; + return __u.__a; + } +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __scalar_hash<_Tp, 2> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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 + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __scalar_hash<_Tp, 3> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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 + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __scalar_hash<_Tp, 4> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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 + { + union + { + _Tp __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +struct _PairT { + size_t first; + size_t second; +}; + +_LIBCPP_INLINE_VISIBILITY +inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { + typedef __scalar_hash<_PairT> _HashT; + const _PairT __p = {__lhs, __rhs}; + return _HashT()(__p); +} + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp*, size_t> +#endif +{ +_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 + { + union + { + _Tp* __t; + size_t __a; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; +#endif // !_LIBCPP_HAS_NO_CHAR8_T + +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <> +struct _LIBCPP_TEMPLATE_VIS hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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(__v);} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ +}; + +#ifndef _LIBCPP_HAS_NO_INT128 + +template <> +struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> + : public __scalar_hash<__int128_t> +{ +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> + : public __scalar_hash<__uint128_t> +{ +}; + +#endif + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(float __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0f) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0) + return 0; + return __scalar_hash::operator()(__v); + } +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public __scalar_hash +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(long double __v) const _NOEXCEPT + { + // -0.0 and 0.0 should return same hash + if (__v == 0.0L) + return 0; +#if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__s.__c = 0; + __u.__s.__d = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; +#elif defined(__x86_64__) + // Zero out padding bits + union + { + long double __t; + struct + { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b; +#else + return __scalar_hash::operator()(__v); +#endif + } +}; + +#if _LIBCPP_STD_VER > 11 + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template ::value> +struct _LIBCPP_TEMPLATE_VIS __enum_hash +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function<_Tp, size_t> +#endif +{ +_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{}(static_cast(__v)); + } +}; +template +struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; +}; + +template +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 +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public unary_function +#endif +{ +_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; + } +}; +#endif + +#ifndef _LIBCPP_CXX03_LANG +template +using __check_hash_requirements _LIBCPP_NODEBUG = integral_constant::value && + is_move_constructible<_Hash>::value && + __invokable_r::value +>; + +template > +using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant::value && + is_default_constructible<_Hash>::value +>; + +#if _LIBCPP_STD_VER > 14 +template +using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; + +template +using __enable_hash_helper _LIBCPP_NODEBUG = __enable_hash_helper_imp<_Type, + typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type +>; +#else +template +using __enable_hash_helper _LIBCPP_NODEBUG = _Type; +#endif + +#endif // !_LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_HASH_H diff --git a/include/__functional/identity.h b/include/__functional/identity.h new file mode 100644 index 000000000..6b8346b3b --- /dev/null +++ b/include/__functional/identity.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___FUNCTIONAL_IDENTITY_H +#define _LIBCPP___FUNCTIONAL_IDENTITY_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct identity { + template + _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept + { + return _VSTD::forward<_Tp>(__t); + } + + using is_transparent = void; +}; +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_IDENTITY_H diff --git a/include/__functional/invoke.h b/include/__functional/invoke.h new file mode 100644 index 000000000..0e167c75d --- /dev/null +++ b/include/__functional/invoke.h @@ -0,0 +1,100 @@ +// -*- 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_INVOKE_H +#define _LIBCPP___FUNCTIONAL_INVOKE_H + +#include <__config> +#include <__functional/weak_result_type.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template ::value> +struct __invoke_void_return_wrapper +{ +#ifndef _LIBCPP_CXX03_LANG + template + static _Ret __call(_Args&&... __args) { + return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static _Ret __call(_Fn __f) { + return _VSTD::__invoke(__f); + } + + template + static _Ret __call(_Fn __f, _A0& __a0) { + return _VSTD::__invoke(__f, __a0); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { + return _VSTD::__invoke(__f, __a0, __a1); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ + return _VSTD::__invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +template +struct __invoke_void_return_wrapper<_Ret, true> +{ +#ifndef _LIBCPP_CXX03_LANG + template + static void __call(_Args&&... __args) { + _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); + } +#else + template + static void __call(_Fn __f) { + _VSTD::__invoke(__f); + } + + template + static void __call(_Fn __f, _A0& __a0) { + _VSTD::__invoke(__f, __a0); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1) { + _VSTD::__invoke(__f, __a0, __a1); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { + _VSTD::__invoke(__f, __a0, __a1, __a2); + } +#endif +}; + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...> +invoke(_Fn&& __f, _Args&&... __args) + noexcept(is_nothrow_invocable_v<_Fn, _Args...>) +{ + return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_INVOKE_H diff --git a/include/__functional/is_transparent.h b/include/__functional/is_transparent.h new file mode 100644 index 000000000..4a72aa8e2 --- /dev/null +++ b/include/__functional/is_transparent.h @@ -0,0 +1,36 @@ +// -*- 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_IS_TRANSPARENT +#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 11 + +template +struct __is_transparent : false_type {}; + +template +struct __is_transparent<_Tp, _Up, + typename __void_t::type> + : true_type {}; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_IS_TRANSPARENT diff --git a/include/__functional/mem_fn.h b/include/__functional/mem_fn.h new file mode 100644 index 000000000..0ec842334 --- /dev/null +++ b/include/__functional/mem_fn.h @@ -0,0 +1,161 @@ +// -*- 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_MEM_FN_H +#define _LIBCPP___FUNCTIONAL_MEM_FN_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/invoke.h> +#include <__functional/weak_result_type.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __mem_fn +#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public __weak_result_type<_Tp> +#endif +{ +public: + // types + typedef _Tp type; +private: + type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} + +#ifndef _LIBCPP_CXX03_LANG + // invoke + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename __invoke_return::type + operator() (_ArgTypes&&... __args) const { + return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); + } +#else + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0& __a0) const { + return _VSTD::__invoke(__f_, __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0 const& __a0) const { + return _VSTD::__invoke(__f_, __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1& __a1) const { + return _VSTD::__invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1& __a1) const { + return _VSTD::__invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1 const& __a1) const { + return _VSTD::__invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1 const& __a1) const { + return _VSTD::__invoke(__f_, __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(__f_, __a0, __a1, __a2); + } +#endif +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +__mem_fn<_Rp _Tp::*> +mem_fn(_Rp _Tp::* __pm) _NOEXCEPT +{ + return __mem_fn<_Rp _Tp::*>(__pm); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_MEM_FN_H diff --git a/include/__functional/mem_fun_ref.h b/include/__functional/mem_fun_ref.h new file mode 100644 index 000000000..830936c1b --- /dev/null +++ b/include/__functional/mem_fun_ref.h @@ -0,0 +1,173 @@ +// -*- 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_MEM_FUN_REF_H +#define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t + : public unary_function<_Tp*, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t + : public binary_function<_Tp*, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)()) + {return mem_fun_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t + : public unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)(); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t + : public binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap); +public: + _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)()) + {return mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) + {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t + : public unary_function +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const + {return (__p->*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t + : public binary_function +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const + {return (__p->*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_t<_Sp,_Tp> +mem_fun(_Sp (_Tp::*__f)() const) + {return const_mem_fun_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_t<_Sp,_Tp,_Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t + : public unary_function<_Tp, _Sp> +{ + _Sp (_Tp::*__p_)() const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const + {return (__p.*__p_)();} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t + : public binary_function<_Tp, _Ap, _Sp> +{ + _Sp (_Tp::*__p_)(_Ap) const; +public: + _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) + : __p_(__p) {} + _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const + {return (__p.*__p_)(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun_ref_t<_Sp,_Tp> +mem_fun_ref(_Sp (_Tp::*__f)() const) + {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +const_mem_fun1_ref_t<_Sp,_Tp,_Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) + {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H diff --git a/include/__functional/not_fn.h b/include/__functional/not_fn.h new file mode 100644 index 000000000..36aab2eb7 --- /dev/null +++ b/include/__functional/not_fn.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___FUNCTIONAL_NOT_FN_H +#define _LIBCPP___FUNCTIONAL_NOT_FN_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct __not_fn_op { + template + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_AFTER_CXX17 auto operator()(_Args&&... __args) const + noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __not_fn_t : __perfect_forward<__not_fn_op, _Fn> { + using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; +}; + +template , _Fn> && + is_move_constructible_v> +>> +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_AFTER_CXX17 auto not_fn(_Fn&& __f) { + return __not_fn_t>(_VSTD::forward<_Fn>(__f)); +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_NOT_FN_H diff --git a/include/__functional/operations.h b/include/__functional/operations.h new file mode 100644 index 000000000..0c7c6d4fc --- /dev/null +++ b/include/__functional/operations.h @@ -0,0 +1,729 @@ +// -*- 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_OPERATIONS_H +#define _LIBCPP___FUNCTIONAL_OPERATIONS_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/unary_function.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Arithmetic operations + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS plus +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS plus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS minus +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS minus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS multiplies +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS multiplies +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS divides +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS divides +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS modulus +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS modulus +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS negate +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : unary_function<_Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS negate +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(- _VSTD::forward<_Tp>(__x))) + -> decltype( - _VSTD::forward<_Tp>(__x)) + { return - _VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +// Bitwise operations + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_and +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_and +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +#if _LIBCPP_STD_VER > 11 +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct _LIBCPP_TEMPLATE_VIS bit_not +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : unary_function<_Tp, _Tp> +#endif +{ +_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;} +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS bit_not +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(~_VSTD::forward<_Tp>(__x))) + -> decltype( ~_VSTD::forward<_Tp>(__x)) + { return ~_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_or +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_or +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS bit_xor +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, _Tp> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS bit_xor +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// Comparison operations + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS equal_to +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS equal_to +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS not_equal_to +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS not_equal_to +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS less +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS less +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS less_equal +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS less_equal +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS greater_equal +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS greater_equal +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS greater +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS greater +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +// Logical operations + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_and +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_and +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_not +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : unary_function<_Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_not +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_Tp&& __x) const + noexcept(noexcept(!_VSTD::forward<_Tp>(__x))) + -> decltype( !_VSTD::forward<_Tp>(__x)) + { return !_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#if _LIBCPP_STD_VER > 11 +template +#else +template +#endif +struct _LIBCPP_TEMPLATE_VIS logical_or +#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : binary_function<_Tp, _Tp, bool> +#endif +{ +_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;} +}; + +#if _LIBCPP_STD_VER > 11 +template <> +struct _LIBCPP_TEMPLATE_VIS logical_or +{ + template + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } + typedef void is_transparent; +}; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H diff --git a/include/__functional/perfect_forward.h b/include/__functional/perfect_forward.h new file mode 100644 index 000000000..308b304a7 --- /dev/null +++ b/include/__functional/perfect_forward.h @@ -0,0 +1,95 @@ +// -*- 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_PERFECT_FORWARD_H +#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H + +#include <__config> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +struct __perfect_forward_impl; + +template +struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _Bound...> { +private: + tuple<_Bound...> __bound_; + +public: + template , _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 >> + _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 >> + auto operator()(_Args&&...) & = delete; + + template >> + _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 >> + auto operator()(_Args&&...) const& = delete; + + template >> + _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 >> + auto operator()(_Args&&...) && = delete; + + template >> + _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 >> + auto operator()(_Args&&...) const&& = delete; +}; + +// __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. +template +using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H diff --git a/include/__functional/pointer_to_binary_function.h b/include/__functional/pointer_to_binary_function.h new file mode 100644 index 000000000..d4a6c1674 --- /dev/null +++ b/include/__functional/pointer_to_binary_function.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___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H + +#include <__config> +#include <__functional/binary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> +{ + _Result (*__f_)(_Arg1, _Arg2); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const + {return __f_(__x, __y);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__f)(_Arg1,_Arg2)) + {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H diff --git a/include/__functional/pointer_to_unary_function.h b/include/__functional/pointer_to_unary_function.h new file mode 100644 index 000000000..0ac4561cc --- /dev/null +++ b/include/__functional/pointer_to_unary_function.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___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H + +#include <__config> +#include <__functional/unary_function.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function + : public unary_function<_Arg, _Result> +{ + _Result (*__f_)(_Arg); +public: + _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg)) + : __f_(__f) {} + _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const + {return __f_(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY +pointer_to_unary_function<_Arg,_Result> +ptr_fun(_Result (*__f)(_Arg)) + {return pointer_to_unary_function<_Arg,_Result>(__f);} + +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H diff --git a/include/__functional/ranges_operations.h b/include/__functional/ranges_operations.h new file mode 100644 index 000000000..a0ea7ccaf --- /dev/null +++ b/include/__functional/ranges_operations.h @@ -0,0 +1,98 @@ +// -*- 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_RANGES_OPERATIONS_H +#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +namespace ranges { + +struct equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u); + } + + using is_transparent = void; +}; + +struct not_equal_to { + template + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) { + return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)); + } + + using is_transparent = void; +}; + +struct less { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) { + return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u); + } + + using is_transparent = void; +}; + +struct less_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) { + return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)); + } + + using is_transparent = void; +}; + +struct greater { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) { + return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t); + } + + using is_transparent = void; +}; + +struct greater_equal { + template + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const + noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) { + return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)); + } + + using is_transparent = void; +}; + +} // namespace ranges +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H diff --git a/include/__functional/reference_wrapper.h b/include/__functional/reference_wrapper.h new file mode 100644 index 000000000..d04d51568 --- /dev/null +++ b/include/__functional/reference_wrapper.h @@ -0,0 +1,212 @@ +// -*- 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_REFERENCE_WRAPPER_H +#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H + +#include <__config> +#include <__functional/weak_result_type.h> +#include <__memory/addressof.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS reference_wrapper +#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) + : public __weak_result_type<_Tp> +#endif +{ +public: + // types + typedef _Tp type; +private: + type* __f_; + + static void __fun(_Tp&) _NOEXCEPT; + static void __fun(_Tp&&) = delete; + +public: + template ::value, decltype(__fun(declval<_Up>())) > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { + type& __f = static_cast<_Up&&>(__u); + __f_ = _VSTD::addressof(__f); + } + + // access + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + operator type&() const _NOEXCEPT {return *__f_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + type& get() const _NOEXCEPT {return *__f_;} + +#ifndef _LIBCPP_CXX03_LANG + // invoke + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + typename __invoke_of::type + operator() (_ArgTypes&&... __args) const { + return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); + } +#else + + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return::type + operator() () const { + return _VSTD::__invoke(get()); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0& __a0) const { + return _VSTD::__invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return0::type + operator() (_A0 const& __a0) const { + return _VSTD::__invoke(get(), __a0); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1& __a1) const { + return _VSTD::__invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1& __a1) const { + return _VSTD::__invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0& __a0, _A1 const& __a1) const { + return _VSTD::__invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return1::type + operator() (_A0 const& __a0, _A1 const& __a1) const { + return _VSTD::__invoke(get(), __a0, __a1); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } + + template + _LIBCPP_INLINE_VISIBILITY + typename __invoke_return2::type + operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { + return _VSTD::__invoke(get(), __a0, __a1, __a2); + } +#endif // _LIBCPP_CXX03_LANG +}; + +#if _LIBCPP_STD_VER > 14 +template +reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +reference_wrapper<_Tp> +ref(_Tp& __t) _NOEXCEPT +{ + return reference_wrapper<_Tp>(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +reference_wrapper +cref(const _Tp& __t) _NOEXCEPT +{ + return reference_wrapper(__t); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT +{ + return __t; +} + +template void ref(const _Tp&&) = delete; +template void cref(const _Tp&&) = delete; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H diff --git a/include/__functional/unary_function.h b/include/__functional/unary_function.h new file mode 100644 index 000000000..499f99646 --- /dev/null +++ b/include/__functional/unary_function.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___FUNCTIONAL_UNARY_FUNCTION_H +#define _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS unary_function +{ + typedef _Arg argument_type; + typedef _Result result_type; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H diff --git a/include/__functional/unary_negate.h b/include/__functional/unary_negate.h new file mode 100644 index 000000000..71257cf40 --- /dev/null +++ b/include/__functional/unary_negate.h @@ -0,0 +1,47 @@ +// -*- 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_UNARY_NEGATE_H +#define _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H + +#include <__config> +#include <__functional/unary_function.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_NEGATORS) + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate + : public unary_function +{ + _Predicate __pred_; +public: + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + explicit unary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + bool operator()(const typename _Predicate::argument_type& __x) const + {return !__pred_(__x);} +}; + +template +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +unary_negate<_Predicate> +not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H diff --git a/include/__functional/unwrap_ref.h b/include/__functional/unwrap_ref.h new file mode 100644 index 000000000..dc309add9 --- /dev/null +++ b/include/__functional/unwrap_ref.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___FUNCTIONAL_UNWRAP_REF_H +#define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; }; + +template +class reference_wrapper; + +template +struct __unwrap_reference > { typedef _LIBCPP_NODEBUG _Tp& type; }; + +template +struct decay; + +#if _LIBCPP_STD_VER > 17 +template +struct unwrap_reference : __unwrap_reference<_Tp> { }; + +template +using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + +template +struct unwrap_ref_decay : unwrap_reference::type> { }; + +template +using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; +#endif // > C++17 + +template +struct __unwrap_ref_decay +#if _LIBCPP_STD_VER > 17 + : unwrap_ref_decay<_Tp> +#else + : __unwrap_reference::type> +#endif +{ }; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H diff --git a/include/__functional/weak_result_type.h b/include/__functional/weak_result_type.h new file mode 100644 index 000000000..32b1e0b1c --- /dev/null +++ b/include/__functional/weak_result_type.h @@ -0,0 +1,481 @@ +// -*- 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_WEAK_RESULT_TYPE_H +#define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H + +#include <__config> +#include <__functional/binary_function.h> +#include <__functional/unary_function.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __has_result_type +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::result_type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + +// __weak_result_type + +template +struct __derives_from_unary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static unary_function<_Ap, _Rp> + __test(const volatile unary_function<_Ap, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template +struct __derives_from_binary_function +{ +private: + struct __two {char __lx; char __lxx;}; + static __two __test(...); + template + static binary_function<_A1, _A2, _Rp> + __test(const volatile binary_function<_A1, _A2, _Rp>*); +public: + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; +}; + +template ::value> +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_unary_function<_Tp, false> +{ +}; + +template ::value> +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type +{ +}; + +template +struct __maybe_derive_from_binary_function<_Tp, false> +{ +}; + +template ::value> +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; +}; + +template +struct __weak_result_type_imp<_Tp, false> + : public __maybe_derive_from_unary_function<_Tp>, + public __maybe_derive_from_binary_function<_Tp> +{ +}; + +template +struct __weak_result_type + : public __weak_result_type_imp<_Tp> +{ +}; + +// 0 argument case + +template +struct __weak_result_type<_Rp ()> +{ + typedef _LIBCPP_NODEBUG _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)()> +{ + typedef _LIBCPP_NODEBUG _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)()> +{ + typedef _LIBCPP_NODEBUG _Rp result_type; +}; + +// 1 argument case + +template +struct __weak_result_type<_Rp (_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1)> + : public unary_function<_A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)()> + : public unary_function<_Cp*, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() volatile> + : public unary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)() const volatile> + : public unary_function +{ +}; + +// 2 argument case + +template +struct __weak_result_type<_Rp (_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1)> + : public binary_function<_Cp*, _A1, _Rp> +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> + : public binary_function +{ +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> + : public binary_function +{ +}; + + +#ifndef _LIBCPP_CXX03_LANG +// 3 or more arguments + +template +struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> +{ + typedef _Rp result_type; +}; + +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> +{ + typedef _Rp result_type; +}; + +template +struct __invoke_return +{ + typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type; +}; + +#else // defined(_LIBCPP_CXX03_LANG) + +template +struct __enable_invoke_imp; + +template +struct __enable_invoke_imp<_Ret, _T1, true, true> { + typedef _Ret _Bullet1; + typedef _Bullet1 type; +}; + +template +struct __enable_invoke_imp<_Ret, _T1, true, false> { + typedef _Ret _Bullet2; + typedef _Bullet2 type; +}; + +template +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 +struct __enable_invoke_imp<_Ret, _T1, false, false> { + typedef typename add_lvalue_reference< + typename __apply_cv()), _Ret>::type + >::type _Bullet4; + typedef _Bullet4 type; +}; + +template +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 _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 +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1) { + return (__t1.*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet1 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return (__t1.*__f)(__a0); +} + +template +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 +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 +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1) { + return ((*__t1).*__f)(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet2 +__invoke(_Fn __f, _T1& __t1, _A0& __a0) { + return ((*__t1).*__f)(__a0); +} + +template +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 +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 +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet3 +__invoke(_Fn __f, _T1& __t1) { + return __t1.*__f; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __enable_invoke<_Fn, _T1>::_Bullet4 +__invoke(_Fn __f, _T1& __t1) { + return (*__t1).*__f; +} + +// fifth bullet + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(declval<_Fp&>()()) +__invoke(_Fp& __f) +{ + return __f(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(declval<_Fp&>()(declval<_A0&>())) +__invoke(_Fp& __f, _A0& __a0) +{ + return __f(__a0); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>())) +__invoke(_Fp& __f, _A0& __a0, _A1& __a1) +{ + return __f(__a0, __a1); +} + +template +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 >::value> +struct __invoke_return +{ + typedef typename __weak_result_type<_Fp>::result_type type; +}; + +template +struct __invoke_return<_Fp, false> +{ + typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type; +}; + +template +struct __invoke_return0 +{ + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type; +}; + +template +struct __invoke_return0<_Rp _Tp::*, _A0> +{ + typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; +}; + +template +struct __invoke_return1 +{ + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), + declval<_A1&>())) type; +}; + +template +struct __invoke_return1<_Rp _Class::*, _A0, _A1> { + typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; +}; + +template +struct __invoke_return2 +{ + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), + declval<_A1&>(), + declval<_A2&>())) type; +}; + +template +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/include/__functional_03 b/include/__functional_03 deleted file mode 100644 index a90cbb75b..000000000 --- a/include/__functional_03 +++ /dev/null @@ -1,1591 +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_03 -#define _LIBCPP_FUNCTIONAL_03 - -// manual variadic expansion for - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -namespace __function { - -template class __base; - -template -class __base<_Rp()> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()() = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0, _A1)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0, _A1) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0, _A1, _A2)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0, _A1, _A2) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template class __func; - -template -class __func<_Fp, _Alloc, _Rp()> - : public __base<_Rp()> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} - explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp()>* __clone() const; - virtual void __clone(__base<_Rp()>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp()>* -__func<_Fp, _Alloc, _Rp()>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const -{ - ::new (__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp()>::operator()() -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first()); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp()>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0)> - : public __base<_Rp(_A0)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0)>* __clone() const; - virtual void __clone(__base<_Rp(_A0)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0)>* -__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const -{ - ::new (__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0, _A1)> - : public __base<_Rp(_A0, _A1)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0, _A1)>* __clone() const; - virtual void __clone(__base<_Rp(_A0, _A1)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0, _A1); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0, _A1)>* -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const -{ - ::new (__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0, __a1); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> - : public __base<_Rp(_A0, _A1, _A2)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; - virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0, _A1, _A2); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0, _A1, _A2)>* -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const -{ - ::new (__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0, __a1, __a2); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -} // __function - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp()> -{ - typedef __function::__base<_Rp()> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2()>&) const;// = delete; - template - bool operator!=(const function<_R2()>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()() const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp()>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp()>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp()>& -function<_Rp()>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp()>& -function<_Rp()>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp()>& ->::type -function<_Rp()>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp()>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp()>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp()>::operator()() const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp()>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp()>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp()>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> - : public unary_function<_A0, _Rp> -{ - typedef __function::__base<_Rp(_A0)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0)>& -function<_Rp(_A0)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0)>& -function<_Rp(_A0)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0)>& ->::type -function<_Rp(_A0)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0)>::operator()(_A0 __a0) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> - : public binary_function<_A0, _A1, _Rp> -{ - typedef __function::__base<_Rp(_A0, _A1)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0, _A1) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0, _A1)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0, _A1)>& -function<_Rp(_A0, _A1)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0, _A1)>& -function<_Rp(_A0, _A1)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0, _A1)>& ->::type -function<_Rp(_A0, _A1)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0, _A1)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0, _A1)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0, __a1); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0, _A1)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0, _A1)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0, _A1)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> -{ - typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0, _A1, _A2) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0, _A1, _A2)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, - const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0, _A1, _A2)>& -function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0, _A1, _A2)>& -function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0, _A1, _A2)>& ->::type -function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0, _A1, _A2)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0, _A1, _A2)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0, __a1, __a2); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0, _A1, _A2)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0, _A1, _A2)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0, _A1, _A2)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -void -swap(function<_Fp>& __x, function<_Fp>& __y) -{return __x.swap(__y);} - -#endif // _LIBCPP_FUNCTIONAL_03 diff --git a/include/__functional_base b/include/__functional_base index ca761c409..ccc3f3a58 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -11,642 +11,22 @@ #define _LIBCPP_FUNCTIONAL_BASE #include <__config> -#include -#include +#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 #include +#include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -_LIBCPP_BEGIN_NAMESPACE_STD - -template -struct _LIBCPP_TEMPLATE_VIS binary_function -{ - typedef _Arg1 first_argument_type; - typedef _Arg2 second_argument_type; - typedef _Result result_type; -}; - -template -struct __has_result_type -{ -private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename _Up::result_type* = 0); -public: - static const bool value = sizeof(__test<_Tp>(0)) == 1; -}; - -#if _LIBCPP_STD_VER > 11 -template -#else -template -#endif -struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> -{ - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x < __y;} -}; - -#if _LIBCPP_STD_VER > 11 -template <> -struct _LIBCPP_TEMPLATE_VIS less -{ - template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } - typedef void is_transparent; -}; -#endif - -// __weak_result_type - -template -struct __derives_from_unary_function -{ -private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static unary_function<_Ap, _Rp> - __test(const volatile unary_function<_Ap, _Rp>*); -public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; -}; - -template -struct __derives_from_binary_function -{ -private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static binary_function<_A1, _A2, _Rp> - __test(const volatile binary_function<_A1, _A2, _Rp>*); -public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; -}; - -template ::value> -struct __maybe_derive_from_unary_function // bool is true - : public __derives_from_unary_function<_Tp>::type -{ -}; - -template -struct __maybe_derive_from_unary_function<_Tp, false> -{ -}; - -template ::value> -struct __maybe_derive_from_binary_function // bool is true - : public __derives_from_binary_function<_Tp>::type -{ -}; - -template -struct __maybe_derive_from_binary_function<_Tp, false> -{ -}; - -template ::value> -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_TYPE typename _Tp::result_type result_type; -}; - -template -struct __weak_result_type_imp<_Tp, false> - : public __maybe_derive_from_unary_function<_Tp>, - public __maybe_derive_from_binary_function<_Tp> -{ -}; - -template -struct __weak_result_type - : public __weak_result_type_imp<_Tp> -{ -}; - -// 0 argument case - -template -struct __weak_result_type<_Rp ()> -{ - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (&)()> -{ - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (*)()> -{ - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; -}; - -// 1 argument case - -template -struct __weak_result_type<_Rp (_A1)> - : public unary_function<_A1, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (&)(_A1)> - : public unary_function<_A1, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (*)(_A1)> - : public unary_function<_A1, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)()> - : public unary_function<_Cp*, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)() const> - : public unary_function -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)() volatile> - : public unary_function -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)() const volatile> - : public unary_function -{ -}; - -// 2 argument case - -template -struct __weak_result_type<_Rp (_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (*)(_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (&)(_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1)> - : public binary_function<_Cp*, _A1, _Rp> -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const> - : public binary_function -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> - : public binary_function -{ -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> - : public binary_function -{ -}; - - -#ifndef _LIBCPP_CXX03_LANG -// 3 or more arguments - -template -struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> -{ - typedef _Rp result_type; -}; - -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> -{ - typedef _Rp result_type; -}; - -template -struct __invoke_return -{ - typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; -}; - -#else // defined(_LIBCPP_CXX03_LANG) - -#include <__functional_base_03> - -#endif // !defined(_LIBCPP_CXX03_LANG) - - -template -struct __invoke_void_return_wrapper -{ -#ifndef _LIBCPP_CXX03_LANG - template - static _Ret __call(_Args&&... __args) { - return __invoke(_VSTD::forward<_Args>(__args)...); - } -#else - template - static _Ret __call(_Fn __f) { - return __invoke(__f); - } - - template - static _Ret __call(_Fn __f, _A0& __a0) { - return __invoke(__f, __a0); - } - - template - static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { - return __invoke(__f, __a0, __a1); - } - - template - static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ - return __invoke(__f, __a0, __a1, __a2); - } -#endif -}; - -template <> -struct __invoke_void_return_wrapper -{ -#ifndef _LIBCPP_CXX03_LANG - template - static void __call(_Args&&... __args) { - __invoke(_VSTD::forward<_Args>(__args)...); - } -#else - template - static void __call(_Fn __f) { - __invoke(__f); - } - - template - static void __call(_Fn __f, _A0& __a0) { - __invoke(__f, __a0); - } - - template - static void __call(_Fn __f, _A0& __a0, _A1& __a1) { - __invoke(__f, __a0, __a1); - } - - template - static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { - __invoke(__f, __a0, __a1, __a2); - } -#endif -}; - -template -class _LIBCPP_TEMPLATE_VIS reference_wrapper - : public __weak_result_type<_Tp> -{ -public: - // types - typedef _Tp type; -private: - type* __f_; - -public: - // construct/copy/destroy - _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT - : __f_(_VSTD::addressof(__f)) {} -#ifndef _LIBCPP_CXX03_LANG - private: reference_wrapper(type&&); public: // = delete; // do not bind to temps -#endif - - // access - _LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;} - _LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;} - -#ifndef _LIBCPP_CXX03_LANG - // invoke - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_of::type - operator() (_ArgTypes&&... __args) const { - return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); - } -#else - - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return::type - operator() () const { - return __invoke(get()); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0& __a0) const { - return __invoke(get(), __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0 const& __a0) const { - return __invoke(get(), __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1& __a1) const { - return __invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1& __a1) const { - return __invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1 const& __a1) const { - return __invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1 const& __a1) const { - return __invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); - } -#endif // _LIBCPP_CXX03_LANG -}; - - -template -inline _LIBCPP_INLINE_VISIBILITY -reference_wrapper<_Tp> -ref(_Tp& __t) _NOEXCEPT -{ - return reference_wrapper<_Tp>(__t); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -reference_wrapper<_Tp> -ref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return ref(__t.get()); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -reference_wrapper -cref(const _Tp& __t) _NOEXCEPT -{ - return reference_wrapper(__t); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -reference_wrapper -cref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return cref(__t.get()); -} - -#ifndef _LIBCPP_CXX03_LANG -template void ref(const _Tp&&) = delete; -template void cref(const _Tp&&) = delete; -#endif - -#if _LIBCPP_STD_VER > 11 -template -struct __is_transparent : false_type {}; - -template -struct __is_transparent<_Tp, _Up, - typename __void_t::type> - : true_type {}; -#endif - -// allocator_arg_t - -struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; - -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; -#else -/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); -#endif - -// uses_allocator - -template -struct __has_allocator_type -{ -private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename _Up::allocator_type* = 0); -public: - static const bool value = sizeof(__test<_Tp>(0)) == 1; -}; - -template ::value> -struct __uses_allocator - : public integral_constant::value> -{ -}; - -template -struct __uses_allocator<_Tp, _Alloc, false> - : public false_type -{ -}; - -template -struct _LIBCPP_TEMPLATE_VIS uses_allocator - : public __uses_allocator<_Tp, _Alloc> -{ -}; - -#if _LIBCPP_STD_VER > 14 -template -_LIBCPP_INLINE_VAR constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; -#endif - -#ifndef _LIBCPP_CXX03_LANG - -// allocator construction - -template -struct __uses_alloc_ctor_imp -{ - typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc; - static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; - static const bool __ic = - is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; - static const int value = __ua ? 2 - __ic : 0; -}; - -template -struct __uses_alloc_ctor - : integral_constant::value> - {}; - -template -inline _LIBCPP_INLINE_VISIBILITY -void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &, _Args &&... __args ) -{ - new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); -} - -// FIXME: This should have a version which takes a non-const alloc. -template -inline _LIBCPP_INLINE_VISIBILITY -void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) -{ - new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); -} - -// FIXME: This should have a version which takes a non-const alloc. -template -inline _LIBCPP_INLINE_VISIBILITY -void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) -{ - new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); -} - -#endif // _LIBCPP_CXX03_LANG - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_FUNCTIONAL_BASE +#endif // _LIBCPP_FUNCTIONAL_BASE diff --git a/include/__functional_base_03 b/include/__functional_base_03 deleted file mode 100644 index e6dac90c8..000000000 --- a/include/__functional_base_03 +++ /dev/null @@ -1,223 +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_03 -#define _LIBCPP_FUNCTIONAL_BASE_03 - -// manual variadic expansion for - -// __invoke - -template -struct __enable_invoke_imp; - -template -struct __enable_invoke_imp<_Ret, _T1, true, true> { - typedef _Ret _Bullet1; - typedef _Bullet1 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, true, false> { - typedef _Ret _Bullet2; - typedef _Bullet2 type; -}; - -template -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 -struct __enable_invoke_imp<_Ret, _T1, false, false> { - typedef typename add_lvalue_reference< - typename __apply_cv()), _Ret>::type - >::type _Bullet4; - typedef _Bullet4 type; -}; - -template -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 _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 -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1) { - return (__t1.*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return (__t1.*__f)(__a0); -} - -template -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 -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 -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1) { - return ((*__t1).*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return ((*__t1).*__f)(__a0); -} - -template -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 -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 -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet3 -__invoke(_Fn __f, _T1& __t1) { - return __t1.*__f; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet4 -__invoke(_Fn __f, _T1& __t1) { - return (*__t1).*__f; -} - -// fifth bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()()) -__invoke(_Fp& __f) -{ - return __f(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) -__invoke(_Fp& __f, _A0& __a0) -{ - return __f(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1) -{ - return __f(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) -{ - return __f(__a0, __a1, __a2); -} - -template >::value> -struct __invoke_return -{ - typedef typename __weak_result_type<_Fp>::result_type type; -}; - -template -struct __invoke_return<_Fp, false> -{ - typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; -}; - -template -struct __invoke_return0 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; -}; - -template -struct __invoke_return0<_Rp _Tp::*, _A0> -{ - typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; -}; - -template -struct __invoke_return1 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>())) type; -}; - -template -struct __invoke_return1<_Rp _Class::*, _A0, _A1> { - typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; -}; - -template -struct __invoke_return2 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>(), - _VSTD::declval<_A2&>())) type; -}; - -template -struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { - typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; -}; -#endif // _LIBCPP_FUNCTIONAL_BASE_03 diff --git a/include/__hash_table b/include/__hash_table index 0b953f58e..adc732cff 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -10,16 +10,16 @@ #ifndef _LIBCPP__HASH_TABLE #define _LIBCPP__HASH_TABLE +#include <__bits> // __libcpp_clz #include <__config> -#include -#include -#include +#include <__debug> #include #include -#include +#include +#include +#include #include - -#include <__debug> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -34,19 +34,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __hash_value_type; -#ifndef _LIBCPP_CXX03_LANG template struct __is_hash_value_type_imp : false_type {}; template -struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value>> : true_type {}; +struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; template struct __is_hash_value_type : false_type {}; template struct __is_hash_value_type<_One> : __is_hash_value_type_imp::type> {}; -#endif _LIBCPP_FUNC_VIS size_t __next_prime(size_t __n); @@ -91,7 +89,7 @@ struct __hash_node_base }; template -struct __hash_node +struct _LIBCPP_STANDALONE_DEBUG __hash_node : public __hash_node_base < typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type @@ -122,7 +120,7 @@ inline _LIBCPP_INLINE_VISIBILITY size_t __next_hash_pow2(size_t __n) { - return __n < 2 ? __n : (size_t(1) << (std::numeric_limits::digits - __libcpp_clz(__n-1))); + return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n-1))); } @@ -155,12 +153,10 @@ struct __hash_key_value_types { static __container_value_type* __get_ptr(__node_value_type& __n) { return _VSTD::addressof(__n); } -#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY static __container_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v); } -#endif }; template @@ -197,13 +193,10 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { static __container_value_type* __get_ptr(__node_value_type& __n) { return _VSTD::addressof(__n.__get_value()); } -#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY static pair __move(__node_value_type& __v) { return __v.__move(); } -#endif - }; template , @@ -295,15 +288,15 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + _VSTD::__debug_db_insert_i(this); } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_iterator(const __hash_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -315,14 +308,14 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator=(const __hash_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif // _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -341,7 +334,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator++() { _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container iterator"); + "Attempted to increment a non-incrementable unordered container iterator"); __node_ = __node_->__next_; return *this; } @@ -364,7 +357,7 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) @@ -405,22 +398,24 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) { - _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); +#endif } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __hash_const_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -432,14 +427,14 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator=(const __hash_const_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif // _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -457,7 +452,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator++() { _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container const_iterator"); + "Attempted to increment a non-incrementable unordered container const_iterator"); __node_ = __node_->__next_; return *this; } @@ -480,7 +475,7 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) @@ -518,17 +513,17 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + _VSTD::__debug_db_insert_i(this); } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_local_iterator(const __hash_local_iterator& __i) : __node_(__i.__node_), __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -540,16 +535,16 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator=(const __hash_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif // _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -568,7 +563,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator++() { _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container local_iterator"); + "Attempted to increment a non-incrementable unordered container local_iterator"); __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; @@ -593,7 +588,7 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 +#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 @@ -650,7 +645,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -659,17 +654,19 @@ public: __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) { - _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); +#endif } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(const __hash_const_local_iterator& __i) : __node_(__i.__node_), __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -681,16 +678,16 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif // _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -709,7 +706,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator++() { _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container const_local_iterator"); + "Attempted to increment a non-incrementable unordered container const_local_iterator"); __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; @@ -734,11 +731,11 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__next_pointer __node, size_t __bucket, + __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, size_t __bucket_count, const void* __c) _NOEXCEPT - : __node_(__node), + : __node_(__node_ptr), __bucket_(__bucket), __bucket_count_(__bucket_count) { @@ -748,9 +745,9 @@ private: } #else _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__next_pointer __node, size_t __bucket, + __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, size_t __bucket_count) _NOEXCEPT - : __node_(__node), + : __node_(__node_ptr), __bucket_(__bucket), __bucket_count_(__bucket_count) { @@ -776,14 +773,13 @@ public: _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __data_(0) {} + : __data_(0, __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator(const allocator_type& __a, size_type __size) _NOEXCEPT_(is_nothrow_copy_constructible::value) : __data_(__size, __a) {} -#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator(__bucket_list_deallocator&& __x) _NOEXCEPT_(is_nothrow_move_constructible::value) @@ -791,7 +787,6 @@ public: { __x.size() = 0; } -#endif _LIBCPP_INLINE_VISIBILITY size_type& size() _NOEXCEPT {return __data_.first();} @@ -825,11 +820,13 @@ private: allocator_type& __na_; - __hash_node_destructor& operator=(const __hash_node_destructor&); - public: bool __value_constructed; + __hash_node_destructor(__hash_node_destructor const&) = default; + __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + + _LIBCPP_INLINE_VISIBILITY explicit __hash_node_destructor(allocator_type& __na, bool __constructed = false) _NOEXCEPT @@ -1005,7 +1002,6 @@ public: explicit __hash_table(const allocator_type& __a); __hash_table(const __hash_table& __u); __hash_table(const __hash_table& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG __hash_table(__hash_table&& __u) _NOEXCEPT_( is_nothrow_move_constructible<__bucket_list>::value && @@ -1014,11 +1010,9 @@ public: is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); __hash_table(__hash_table&& __u, const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG ~__hash_table(); __hash_table& operator=(const __hash_table& __u); -#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY __hash_table& operator=(__hash_table&& __u) _NOEXCEPT_( @@ -1026,7 +1020,6 @@ public: is_nothrow_move_assignable<__node_allocator>::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); -#endif template void __assign_unique(_InputIterator __first, _InputIterator __last); template @@ -1035,7 +1028,7 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { - return std::min( + return _VSTD::min( __node_traits::max_size(__node_alloc()), numeric_limits::max() ); @@ -1064,7 +1057,6 @@ public: iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); -#ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); @@ -1149,15 +1141,6 @@ public: return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); } -#else // !defined(_LIBCPP_CXX03_LANG) - template - _LIBCPP_INLINE_VISIBILITY - pair __emplace_unique_key_args(_Key const&, _Args& __args); - - iterator __insert_multi(const __container_value_type& __x); - iterator __insert_multi(const_iterator __p, const __container_value_type& __x); -#endif - _LIBCPP_INLINE_VISIBILITY pair __insert_unique(const __container_value_type& __x) { return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); @@ -1293,7 +1276,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 +#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()); @@ -1306,7 +1289,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return local_iterator(nullptr, __n, bucket_count(), this); #else return local_iterator(nullptr, __n, bucket_count()); @@ -1319,7 +1302,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 +#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()); @@ -1332,35 +1315,30 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 +#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 +#if _LIBCPP_DEBUG_LEVEL == 2 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_DEBUG_LEVEL == 2 private: void __rehash(size_type __n); -#ifndef _LIBCPP_CXX03_LANG template __node_holder __construct_node(_Args&& ...__args); template __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); -#else // _LIBCPP_CXX03_LANG - __node_holder __construct_node(const __container_value_type& __v); - __node_holder __construct_node_hash(size_t __hash, const __container_value_type& __v); -#endif _LIBCPP_INLINE_VISIBILITY @@ -1371,7 +1349,6 @@ private: _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __hash_table&, false_type) {} -#ifndef _LIBCPP_CXX03_LANG void __move_assign(__hash_table& __u, false_type); void __move_assign(__hash_table& __u, true_type) _NOEXCEPT_( @@ -1398,7 +1375,6 @@ private: } _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} -#endif // _LIBCPP_CXX03_LANG void __deallocate_node(__next_pointer __np) _NOEXCEPT; __next_pointer __detach() _NOEXCEPT; @@ -1416,8 +1392,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() is_nothrow_default_constructible<__node_allocator>::value && is_nothrow_default_constructible::value && is_nothrow_default_constructible::value) - : __p2_(0), - __p3_(1.0f) + : __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) { } @@ -1437,7 +1413,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __hf), __p3_(1.0f, __eql) { @@ -1446,9 +1422,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), - __p2_(0), - __p3_(1.0f) + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) { } @@ -1458,7 +1434,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) __bucket_list_deleter(allocator_traits<__pointer_allocator>:: select_on_container_copy_construction( __u.__bucket_list_.get_deleter().__alloc()), 0)), - __p1_(__second_tag(), allocator_traits<__node_allocator>:: + __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: select_on_container_copy_construction(__u.__node_alloc())), __p2_(0, __u.hash_function()), __p3_(__u.__p3_) @@ -1469,14 +1445,12 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __u.hash_function()), __p3_(__u.__p3_) { } -#ifndef _LIBCPP_CXX03_LANG - template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_( @@ -1503,7 +1477,7 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, _VSTD::move(__u.hash_function())), __p3_(_VSTD::move(__u.__p3_)) { @@ -1524,8 +1498,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, } } -#endif // _LIBCPP_CXX03_LANG - template __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { @@ -1537,7 +1509,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() #endif __deallocate_node(__p1_.first().__next_); -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->__erase_c(this); #endif } @@ -1561,7 +1533,7 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) { - if (this != &__u) + if (this != _VSTD::addressof(__u)) { __copy_assign_alloc(__u); hash_function() = __u.hash_function(); @@ -1581,7 +1553,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 +#if _LIBCPP_DEBUG_LEVEL == 2 __c_node* __c = __get_db()->__find_c_and_lock(this); for (__i_node** __p = __c->end_; __p != __c->beg_; ) { @@ -1591,7 +1563,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) { (*__p)->__c_ = nullptr; if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); } } __get_db()->unlock(); @@ -1616,8 +1588,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT return __cache; } -#ifndef _LIBCPP_CXX03_LANG - template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( @@ -1644,8 +1614,8 @@ __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, &__u); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1667,7 +1637,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( #ifndef _LIBCPP_NO_EXCEPTIONS try { -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS const_iterator __i = __u.begin(); while (__cache != nullptr && __u.size() != 0) { @@ -1684,7 +1654,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __deallocate_node(__cache); throw; } -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS __deallocate_node(__cache); } const_iterator __i = __u.begin(); @@ -1712,8 +1682,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) return *this; } -#endif // _LIBCPP_CXX03_LANG - template template void @@ -1731,7 +1699,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first #ifndef _LIBCPP_NO_EXCEPTIONS try { -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { __cache->__upcast()->__value_ = *__first; @@ -1746,7 +1714,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first __deallocate_node(__cache); throw; } -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS __deallocate_node(__cache); } for (; __first != __last; ++__first) @@ -1771,7 +1739,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, #ifndef _LIBCPP_NO_EXCEPTIONS try { -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { __cache->__upcast()->__value_ = *__first; @@ -1786,7 +1754,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, __deallocate_node(__cache); throw; } -#endif // _LIBCPP_NO_EXCEPTIONS +#endif // _LIBCPP_NO_EXCEPTIONS __deallocate_node(__cache); } for (; __first != __last; ++__first) @@ -1798,7 +1766,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__p1_.first().__next_, this); #else return iterator(__p1_.first().__next_); @@ -1810,7 +1778,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(nullptr, this); #else return iterator(nullptr); @@ -1822,7 +1790,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(__p1_.first().__next_, this); #else return const_iterator(__p1_.first().__next_); @@ -1834,7 +1802,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(nullptr, this); #else return const_iterator(nullptr); @@ -1943,7 +1911,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ __existing_node = __nd->__ptr(); __inserted = true; } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return pair(iterator(__existing_node, this), __inserted); #else return pair(iterator(__existing_node), __inserted); @@ -1953,7 +1921,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ // Prepare the container for an insertion of the value __cp_val with the hash // __cp_hash. This does a lookup into the container to see if __cp_value is // already present, and performs a rehash if necessary. Returns a pointer to the -// last occurance of __cp_val in the map. +// last occurrence of __cp_val in the map. // // Note that this function does forward exceptions if key_eq() throws, and never // mutates __value or actually inserts into the map. @@ -2041,7 +2009,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__cp->__ptr(), this); #else return iterator(__cp->__ptr()); @@ -2053,11 +2021,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( const_iterator __p, __node_pointer __cp) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); if (__p != end() && key_eq()(*__p, __cp->__value_)) { __next_pointer __np = __p.__node_; @@ -2076,7 +2042,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(static_cast<__next_pointer>(__cp), this); #else return iterator(static_cast<__next_pointer>(__cp)); @@ -2087,17 +2053,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( -#ifndef _LIBCPP_CXX03_LANG template template pair::iterator, bool> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) -#else -template -template -pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args& __args) -#endif { size_t __hash = hash_function()(__k); @@ -2121,11 +2080,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& } } { -#ifndef _LIBCPP_CXX03_LANG __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); -#else - __node_holder __h = __construct_node_hash(__hash, __args); -#endif if (size()+1 > __bc * max_load_factor() || __bc == 0) { rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), @@ -2157,15 +2112,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __inserted = true; } __done: -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return pair(iterator(__nd, this), __inserted); #else return pair(iterator(__nd), __inserted); #endif } -#ifndef _LIBCPP_CXX03_LANG - template template pair::iterator, bool> @@ -2195,47 +2148,15 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); return __r; } -#else // _LIBCPP_CXX03_LANG - -template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const __container_value_type& __x) -{ - __node_holder __h = __construct_node(__x); - iterator __r = __node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, - const __container_value_type& __x) -{ -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::insert(const_iterator, lvalue) called with an iterator not" - " referring to this unordered container"); -#endif - __node_holder __h = __construct_node(__x); - iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); - return __r; -} - -#endif // _LIBCPP_CXX03_LANG - #if _LIBCPP_STD_VER > 14 template template @@ -2366,7 +2287,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( __node_insert_multi_perform(__src_ptr, __pn); } } -#endif // _LIBCPP_STD_VER > 14 +#endif // _LIBCPP_STD_VER > 14 template void @@ -2397,9 +2318,9 @@ template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) { -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->__invalidate_all(this); -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); @@ -2415,7 +2336,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) size_type __chash = __constrain_hash(__cp->__hash(), __nbc); __bucket_list_[__chash] = __pp; size_type __phash = __chash; - for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { __chash = __constrain_hash(__cp->__hash(), __nbc); @@ -2468,7 +2389,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__nd, this); #else return iterator(__nd); @@ -2499,7 +2420,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 +#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(__nd, this); #else return const_iterator(__nd); @@ -2511,8 +2432,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const return end(); } -#ifndef _LIBCPP_CXX03_LANG - template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder @@ -2548,48 +2467,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( return __h; } -#else // _LIBCPP_CXX03_LANG - -template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const __container_value_type& __v) -{ - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); - __h.get_deleter().__value_constructed = true; - __h->__hash_ = hash_function()(__h->__value_); - __h->__next_ = nullptr; - return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 -} - -template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, - const __container_value_type& __v) -{ - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); - __h.get_deleter().__value_constructed = true; - __h->__hash_ = __hash; - __h->__next_ = nullptr; - return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 -} - -#endif // _LIBCPP_CXX03_LANG - template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __next_pointer __np = __p.__node_; -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container erase(iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__p != end(), - "unordered container erase(iterator) called with a non-dereferenceable iterator"); + _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 iterator __r(__np, this); #else iterator __r(__np); @@ -2604,21 +2492,19 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, - "unodered container::erase(iterator, iterator) called with an iterator not" - " referring to this unodered container"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, - "unodered container::erase(iterator, iterator) called with an iterator not" - " referring to this unodered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); for (const_iterator __p = __first; __first != __last; __p = __first) { ++__first; erase(__p); } __next_pointer __np = __last.__node_; -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 return iterator (__np, this); #else return iterator (__np); @@ -2689,7 +2575,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 +#if _LIBCPP_DEBUG_LEVEL == 2 __c_node* __c = __get_db()->__find_c_and_lock(this); for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) { @@ -2699,7 +2585,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT { (*__dp)->__c_ = nullptr; if (--__c->end_ != __dp) - memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); + _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); } } __get_db()->unlock(); @@ -2828,9 +2714,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __u.__bucket_list_.reset(__npp); } _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); - __swap_allocator(__bucket_list_.get_deleter().__alloc(), + _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc()); - __swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); __p2_.swap(__u.__p2_); __p3_.swap(__u.__p3_); @@ -2840,8 +2726,8 @@ __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, &__u); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -2858,7 +2744,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const { for (__np = __np->__next_; __np != nullptr && __constrain_hash(__np->__hash(), __bc) == __n; - __np = __np->__next_, ++__r) + __np = __np->__next_, (void) ++__r) ; } return __r; @@ -2874,7 +2760,7 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __x.swap(__y); } -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL == 2 template bool @@ -2904,10 +2790,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, return false; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 +#endif // _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP__HASH_TABLE +#endif // _LIBCPP__HASH_TABLE diff --git a/include/__iterator/access.h b/include/__iterator/access.h new file mode 100644 index 000000000..5e0d6b351 --- /dev/null +++ b/include/__iterator/access.h @@ -0,0 +1,129 @@ +// -*- 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_ACCESS_H +#define _LIBCPP___ITERATOR_ACCESS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp* +begin(_Tp (&__array)[_Np]) +{ + return __array; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_Tp* +end(_Tp (&__array)[_Np]) +{ + return __array + _Np; +} + +#if !defined(_LIBCPP_CXX03_LANG) + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto +begin(_Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto +begin(const _Cp& __c) -> decltype(__c.begin()) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto +end(_Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto +end(const _Cp& __c) -> decltype(__c.end()) +{ + return __c.end(); +} + +#if _LIBCPP_STD_VER > 11 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c)) +{ + return _VSTD::begin(__c); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c)) +{ + return _VSTD::end(__c); +} + +#endif + + +#else // defined(_LIBCPP_CXX03_LANG) + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +begin(_Cp& __c) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +begin(const _Cp& __c) +{ + return __c.begin(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::iterator +end(_Cp& __c) +{ + return __c.end(); +} + +template +_LIBCPP_INLINE_VISIBILITY +typename _Cp::const_iterator +end(const _Cp& __c) +{ + return __c.end(); +} + +#endif // !defined(_LIBCPP_CXX03_LANG) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ACCESS_H diff --git a/include/__iterator/advance.h b/include/__iterator/advance.h new file mode 100644 index 000000000..d74d6b8b9 --- /dev/null +++ b/include/__iterator/advance.h @@ -0,0 +1,199 @@ +// -*- 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_ADVANCE_H +#define _LIBCPP___ITERATOR_ADVANCE_H + +#include <__config> +#include <__debug> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { + for (; __n > 0; --__n) + ++__i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { + if (__n >= 0) + for (; __n > 0; --__n) + ++__i; + else + for (; __n < 0; ++__n) + --__i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { + __i += __n; +} + +template < + class _InputIter, class _Distance, + class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())), + class = __enable_if_t::value> > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void advance(_InputIter& __i, _Distance __orig_n) { + typedef typename iterator_traits<_InputIter>::difference_type _Difference; + _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); + _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); +} + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +// [range.iter.op.advance] + +namespace ranges { +namespace __advance { + +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI + static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { + while (__n > 0) { + --__n; + ++__i; + } + } + + template + _LIBCPP_HIDE_FROM_ABI + static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { + while (__n < 0) { + ++__n; + --__i; + } + } + +public: + // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. + template + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { + _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>, + "If `n < 0`, then `bidirectional_iterator` must be true."); + + // If `I` models `random_access_iterator`, equivalent to `i += n`. + if constexpr (random_access_iterator<_Ip>) { + __i += __n; + return; + } else if constexpr (bidirectional_iterator<_Ip>) { + // Otherwise, if `n` is non-negative, increments `i` by `n`. + __advance_forward(__i, __n); + // Otherwise, decrements `i` by `-n`. + __advance_backward(__i, __n); + return; + } else { + // Otherwise, if `n` is non-negative, increments `i` by `n`. + __advance_forward(__i, __n); + return; + } + } + + // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound) denotes a range. + template _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_Ip& __i, _Sp __bound) const { + // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound)`. + if constexpr (assignable_from<_Ip&, _Sp>) { + __i = _VSTD::move(__bound); + } + // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound - i)`. + else if constexpr (sized_sentinel_for<_Sp, _Ip>) { + (*this)(__i, __bound - __i); + } + // Otherwise, while `bool(i != bound)` is true, increments `i`. + else { + while (__i != __bound) { + ++__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`. + // Returns: `n - M`, where `M` is the difference between the the ending and starting position. + template _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const { + _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), + "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); + // If `S` and `I` model `sized_sentinel_for`: + if constexpr (sized_sentinel_for<_Sp, _Ip>) { + // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`. + // __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); + return __n - __M; + } + + // Otherwise, equivalent to `ranges::advance(i, n)`. + (*this)(__i, __n); + return 0; + } else { + // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at + // most `n` times. + while (__i != __bound && __n > 0) { + ++__i; + --__n; + } + + // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times. + if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) { + while (__i != __bound && __n < 0) { + --__i; + ++__n; + } + } + return __n; + } + + _LIBCPP_UNREACHABLE(); + } +}; + +} // namespace __advance + +inline namespace __cpo { + inline constexpr auto advance = __advance::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ADVANCE_H diff --git a/include/__iterator/back_insert_iterator.h b/include/__iterator/back_insert_iterator.h new file mode 100644 index 000000000..844babe5c --- /dev/null +++ b/include/__iterator/back_insert_iterator.h @@ -0,0 +1,70 @@ +// -*- 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_BACK_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS back_insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_) + {container->push_back(__value_); return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_) + {container->push_back(_VSTD::move(__value_)); return *this;} +#endif // _LIBCPP_CXX03_LANG + _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;} +}; + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 +back_insert_iterator<_Container> +back_inserter(_Container& __x) +{ + return back_insert_iterator<_Container>(__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H diff --git a/include/__iterator/common_iterator.h b/include/__iterator/common_iterator.h new file mode 100644 index 000000000..68309ee08 --- /dev/null +++ b/include/__iterator/common_iterator.h @@ -0,0 +1,283 @@ +// -*- 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_COMMON_ITERATOR_H +#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H + +#include <__config> +#include <__debug> +#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/readable_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept __can_use_postfix_proxy = + constructible_from, iter_reference_t<_Iter>> && + move_constructible>; + +template _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: + constexpr const iter_value_t<_Iter>* operator->() const noexcept { + return _VSTD::addressof(__value); + } + }; + + class __postfix_proxy { + friend common_iterator; + + iter_value_t<_Iter> __value; + constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x) + : __value(_VSTD::forward>(__x)) {} + + public: + constexpr const iter_value_t<_Iter>& operator*() const noexcept { + return __value; + } + }; + +public: + variant<_Iter, _Sent> __hold_; + + common_iterator() requires default_initializable<_Iter> = default; + + constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {} + constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {} + + template + requires convertible_to && convertible_to + constexpr common_iterator(const common_iterator<_I2, _S2>& __other) + : __hold_([&]() -> variant<_Iter, _Sent> { + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); + if (__other.__hold_.index() == 0) + return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; + return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; + }()) {} + + template + requires convertible_to && convertible_to && + assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> + common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); + + auto __idx = __hold_.index(); + auto __other_idx = __other.__hold_.index(); + + // If they're the same index, just assign. + if (__idx == 0 && __other_idx == 0) + _VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_); + else if (__idx == 1 && __other_idx == 1) + _VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_); + + // Otherwise replace with the oposite element. + else if (__other_idx == 1) + __hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_)); + else if (__other_idx == 0) + __hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_)); + + return *this; + } + + constexpr decltype(auto) operator*() + { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *_VSTD::__unchecked_get<_Iter>(__hold_); + } + + constexpr decltype(auto) operator*() const + requires __dereferenceable + { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *_VSTD::__unchecked_get<_Iter>(__hold_); + } + + template + decltype(auto) operator->() const + requires indirectly_readable && + (requires(const _I2& __i) { __i.operator->(); } || + is_reference_v> || + constructible_from, iter_reference_t<_I2>>) + { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { + return _VSTD::__unchecked_get<_Iter>(__hold_); + } else if constexpr (is_reference_v>) { + auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_); + return _VSTD::addressof(__tmp); + } else { + return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_)); + } + } + + common_iterator& operator++() { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; + } + + decltype(auto) operator++(int) { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + if constexpr (forward_iterator<_Iter>) { + auto __tmp = *this; + ++*this; + return __tmp; + } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } || + !__can_use_postfix_proxy<_Iter>) { + return _VSTD::__unchecked_get<_Iter>(__hold_)++; + } else { + __postfix_proxy __p(**this); + ++*this; + return __p; + } + } + + template _S2> + requires sentinel_for<_Sent, _I2> + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == __y_index) + return true; + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + template _S2> + requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == 1 && __y_index == 1) + return true; + + if (__x_index == 0 && __y_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + template _I2, sized_sentinel_for<_Iter> _S2> + requires sized_sentinel_for<_Sent, _I2> + friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); + + auto __x_index = __x.__hold_.index(); + auto __y_index = __y.__hold_.index(); + + if (__x_index == 1 && __y_index == 1) + return 0; + + if (__x_index == 0 && __y_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + + if (__x_index == 0) + return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_); + + return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + } + + friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) + noexcept(noexcept(ranges::iter_move(declval()))) + requires input_iterator<_Iter> + { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); + return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); + } + + template _I2, class _S2> + friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) + noexcept(noexcept(ranges::iter_swap(declval(), declval()))) + { + _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT(holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); + } +}; + +template +struct incrementable_traits> { + using difference_type = iter_difference_t<_Iter>; +}; + +template +concept __denotes_forward_iter = + requires { typename iterator_traits<_Iter>::iterator_category; } && + derived_from::iterator_category, forward_iterator_tag>; + +template +concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { + __a.operator->(); +}; + +template +struct __arrow_type_or_void { + using type = void; +}; + +template + requires __common_iter_has_ptr_op<_Iter, _Sent> +struct __arrow_type_or_void<_Iter, _Sent> { + using type = decltype(declval&>().operator->()); +}; + +template +struct iterator_traits> { + using iterator_concept = _If, + forward_iterator_tag, + input_iterator_tag>; + using iterator_category = _If<__denotes_forward_iter<_Iter>, + forward_iterator_tag, + input_iterator_tag>; + using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H diff --git a/include/__iterator/concepts.h b/include/__iterator/concepts.h new file mode 100644 index 000000000..f6d092c75 --- /dev/null +++ b/include/__iterator/concepts.h @@ -0,0 +1,264 @@ +// -*- 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_CONCEPTS_H +#define _LIBCPP___ITERATOR_CONCEPTS_H + +#include <__config> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/pointer_traits.h> +#include <__utility/forward.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [iterator.concept.readable] +template +concept __indirectly_readable_impl = + requires(const _In __i) { + typename iter_value_t<_In>; + typename iter_reference_t<_In>; + typename iter_rvalue_reference_t<_In>; + { *__i } -> same_as>; + { ranges::iter_move(__i) } -> same_as>; + } && + common_reference_with&&, iter_value_t<_In>&> && + common_reference_with&&, iter_rvalue_reference_t<_In>&&> && + common_reference_with&&, const iter_value_t<_In>&>; + +template +concept indirectly_readable = __indirectly_readable_impl>; + +template +using iter_common_reference_t = common_reference_t, iter_value_t<_Tp>&>; + +// [iterator.concept.writable] +template +concept indirectly_writable = + requires(_Out&& __o, _Tp&& __t) { + *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + +// [iterator.concept.winc] +template +concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; + +template +concept __signed_integer_like = signed_integral<_Tp>; + +template +concept weakly_incrementable = + // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). + !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. + movable<_Ip> && + requires(_Ip __i) { + typename iter_difference_t<_Ip>; + requires __signed_integer_like>; + { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving + __i++; // not required to be equality-preserving + }; + +// [iterator.concept.inc] +template +concept incrementable = + regular<_Ip> && + weakly_incrementable<_Ip> && + requires(_Ip __i) { + { __i++ } -> same_as<_Ip>; + }; + +// [iterator.concept.iterator] +template +concept input_or_output_iterator = + requires(_Ip __i) { + { *__i } -> __referenceable; + } && + weakly_incrementable<_Ip>; + +// [iterator.concept.sentinel] +template +concept sentinel_for = + semiregular<_Sp> && + input_or_output_iterator<_Ip> && + __weakly_equality_comparable_with<_Sp, _Ip>; + +template +inline constexpr bool disable_sized_sentinel_for = false; + +template +concept sized_sentinel_for = + sentinel_for<_Sp, _Ip> && + !disable_sized_sentinel_for, remove_cv_t<_Ip>> && + requires(const _Ip& __i, const _Sp& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; + +// [iterator.concept.input] +template +concept input_iterator = + input_or_output_iterator<_Ip> && + indirectly_readable<_Ip> && + requires { typename _ITER_CONCEPT<_Ip>; } && + derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; + +// [iterator.concept.output] +template +concept output_iterator = + input_or_output_iterator<_Ip> && + indirectly_writable<_Ip, _Tp> && + requires (_Ip __it, _Tp&& __t) { + *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + +// [iterator.concept.forward] +template +concept forward_iterator = + input_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && + incrementable<_Ip> && + sentinel_for<_Ip, _Ip>; + +// [iterator.concept.bidir] +template +concept bidirectional_iterator = + forward_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> same_as<_Ip>; + }; + +template +concept random_access_iterator = + bidirectional_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && + totally_ordered<_Ip> && + sized_sentinel_for<_Ip, _Ip> && + requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { + { __i += __n } -> same_as<_Ip&>; + { __j + __n } -> same_as<_Ip>; + { __n + __j } -> same_as<_Ip>; + { __i -= __n } -> same_as<_Ip&>; + { __j - __n } -> same_as<_Ip>; + { __j[__n] } -> same_as>; + }; + +template +concept contiguous_iterator = + random_access_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && + is_lvalue_reference_v> && + same_as, remove_cvref_t>> && + requires(const _Ip& __i) { + { _VSTD::to_address(__i) } -> same_as>>; + }; + +template +concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); }); + +// [indirectcallable.indirectinvocable] +template +concept indirectly_unary_invocable = + indirectly_readable<_It> && + copy_constructible<_Fp> && + invocable<_Fp&, iter_value_t<_It>&> && + invocable<_Fp&, iter_reference_t<_It>> && + invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< + invoke_result_t<_Fp&, iter_value_t<_It>&>, + invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template +concept indirectly_regular_unary_invocable = + indirectly_readable<_It> && + copy_constructible<_Fp> && + regular_invocable<_Fp&, iter_value_t<_It>&> && + regular_invocable<_Fp&, iter_reference_t<_It>> && + regular_invocable<_Fp&, iter_common_reference_t<_It>> && + common_reference_with< + invoke_result_t<_Fp&, iter_value_t<_It>&>, + invoke_result_t<_Fp&, iter_reference_t<_It>>>; + +template +concept indirect_unary_predicate = + indirectly_readable<_It> && + copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It>&> && + predicate<_Fp&, iter_reference_t<_It>> && + predicate<_Fp&, iter_common_reference_t<_It>>; + +template +concept indirect_binary_predicate = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template +concept indirect_equivalence_relation = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template +concept indirect_strict_weak_order = + indirectly_readable<_It1> && indirectly_readable<_It2> && + copy_constructible<_Fp> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + +template + requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> +using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>; + +template +concept indirectly_movable = + indirectly_readable<_In> && + indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; + +template +concept indirectly_movable_storable = + indirectly_movable<_In, _Out> && + indirectly_writable<_Out, iter_value_t<_In>> && + movable> && + constructible_from, iter_rvalue_reference_t<_In>> && + assignable_from&, iter_rvalue_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) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_CONCEPTS_H diff --git a/include/__iterator/counted_iterator.h b/include/__iterator/counted_iterator.h new file mode 100644 index 000000000..aaab3ac77 --- /dev/null +++ b/include/__iterator/counted_iterator.h @@ -0,0 +1,303 @@ +// -*- 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_COUNTED_ITERATOR_H +#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H + +#include <__config> +#include <__debug> +#include <__iterator/concepts.h> +#include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__memory/pointer_traits.h> +#include <__utility/move.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +struct __counted_iterator_concept {}; + +template + requires requires { typename _Iter::iterator_concept; } +struct __counted_iterator_concept<_Iter> { + using iterator_concept = typename _Iter::iterator_concept; +}; + +template +struct __counted_iterator_category {}; + +template + requires requires { typename _Iter::iterator_category; } +struct __counted_iterator_category<_Iter> { + using iterator_category = typename _Iter::iterator_category; +}; + +template +struct __counted_iterator_value_type {}; + +template +struct __counted_iterator_value_type<_Iter> { + using value_type = iter_value_t<_Iter>; +}; + +template +class counted_iterator + : public __counted_iterator_concept<_Iter> + , public __counted_iterator_category<_Iter> + , public __counted_iterator_value_type<_Iter> +{ +public: + [[no_unique_address]] _Iter __current_ = _Iter(); + iter_difference_t<_Iter> __count_ = 0; + + using iterator_type = _Iter; + using difference_type = iter_difference_t<_Iter>; + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator() requires default_initializable<_Iter> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) + : __current_(_VSTD::move(__iter)), __count_(__n) { + _LIBCPP_ASSERT(__n >= 0, "__n must not be negative."); + } + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator(const counted_iterator<_I2>& __other) + : __current_(__other.__current_), __count_(__other.__count_) {} + + template + requires assignable_from<_Iter&, const _I2&> + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { + __current_ = __other.__current_; + __count_ = __other.__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr const _Iter& base() const& noexcept { return __current_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Iter base() && { return _VSTD::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() { + _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() const + requires __dereferenceable + { + _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator->() const noexcept + requires contiguous_iterator<_Iter> + { + return _VSTD::to_address(__current_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator++() { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + ++__current_; + --__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + decltype(auto) operator++(int) { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + --__count_; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { return __current_++; } + catch(...) { ++__count_; throw; } +#else + return __current_++; +#endif // _LIBCPP_NO_EXCEPTIONS + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator++(int) + requires forward_iterator<_Iter> + { + _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + counted_iterator __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator--() + requires bidirectional_iterator<_Iter> + { + --__current_; + ++__count_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator--(int) + requires bidirectional_iterator<_Iter> + { + counted_iterator __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + return counted_iterator(__current_ + __n, __count_ - __n); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr counted_iterator operator+( + iter_difference_t<_Iter> __n, const counted_iterator& __x) + requires random_access_iterator<_Iter> + { + return __x + __n; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end."); + __current_ += __n; + __count_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + return counted_iterator(__current_ - __n, __count_ + __n); + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_I2> operator-( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __rhs.__count_ - __lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Iter> operator-( + const counted_iterator& __lhs, default_sentinel_t) + { + return -__lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_Iter> operator-( + default_sentinel_t, const counted_iterator& __rhs) + { + return __rhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: " + "counted_iterator would be decremented before the " + "first element of its range."); + __current_ -= __n; + __count_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const + requires random_access_iterator<_Iter> + { + _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size."); + return __current_[__n]; + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __lhs.__count_ == __rhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==( + const counted_iterator& __lhs, default_sentinel_t) + { + return __lhs.__count_ == 0; + } + + template _I2> + friend constexpr strong_ordering operator<=>( + const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) + { + return __rhs.__count_ <=> __lhs.__count_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + requires input_iterator<_Iter> + { + _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range."); + return ranges::iter_move(__i.__current_); + } + + template _I2> + _LIBCPP_HIDE_FROM_ABI + friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0, + "Iterators must not be past end of range."); + return ranges::iter_swap(__x.__current_, __y.__current_); + } +}; + +template + requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> +struct iterator_traits> : iterator_traits<_Iter> { + using pointer = conditional_t, + add_pointer_t>, void>; +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H diff --git a/include/__iterator/data.h b/include/__iterator/data.h new file mode 100644 index 000000000..5e4946cc1 --- /dev/null +++ b/include/__iterator/data.h @@ -0,0 +1,51 @@ +// -*- 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_DATA_H +#define _LIBCPP___ITERATOR_DATA_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template constexpr +_LIBCPP_INLINE_VISIBILITY +auto data(_Cont& __c) +_NOEXCEPT_(noexcept(__c.data())) +-> decltype (__c.data()) +{ return __c.data(); } + +template constexpr +_LIBCPP_INLINE_VISIBILITY +auto data(const _Cont& __c) +_NOEXCEPT_(noexcept(__c.data())) +-> decltype (__c.data()) +{ return __c.data(); } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); } + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DATA_H diff --git a/include/__iterator/default_sentinel.h b/include/__iterator/default_sentinel.h new file mode 100644 index 000000000..e12a5909c --- /dev/null +++ b/include/__iterator/default_sentinel.h @@ -0,0 +1,30 @@ +// -*- 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_DEFAULT_SENTINEL_H +#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +struct default_sentinel_t { }; +inline constexpr default_sentinel_t default_sentinel{}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H diff --git a/include/__iterator/distance.h b/include/__iterator/distance.h new file mode 100644 index 000000000..50ed76a4e --- /dev/null +++ b/include/__iterator/distance.h @@ -0,0 +1,107 @@ +// -*- 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_DISTANCE_H +#define _LIBCPP___ITERATOR_DISTANCE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +typename iterator_traits<_InputIter>::difference_type +__distance(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + typename iterator_traits<_InputIter>::difference_type __r(0); + for (; __first != __last; ++__first) + ++__r; + return __r; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +typename iterator_traits<_RandIter>::difference_type +__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) +{ + return __last - __first; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +typename iterator_traits<_InputIter>::difference_type +distance(_InputIter __first, _InputIter __last) +{ + return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); +} + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +// [range.iter.op.distance] + +namespace ranges { +namespace __distance { + +struct __fn { + template _Sp> + requires (!sized_sentinel_for<_Sp, _Ip>) + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { + iter_difference_t<_Ip> __n = 0; + while (__first != __last) { + ++__first; + ++__n; + } + return __n; + } + + template> _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { + if constexpr (sized_sentinel_for<_Sp, __uncvref_t<_Ip>>) { + return __last - __first; + } else { + return __last - decay_t<_Ip>(__first); + } + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { + if constexpr (sized_range<_Rp>) { + return static_cast>(ranges::size(__r)); + } else { + return operator()(ranges::begin(__r), ranges::end(__r)); + } + } +}; + +} // namespace __distance + +inline namespace __cpo { + inline constexpr auto distance = __distance::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_DISTANCE_H diff --git a/include/__iterator/empty.h b/include/__iterator/empty.h new file mode 100644 index 000000000..39cd560a2 --- /dev/null +++ b/include/__iterator/empty.h @@ -0,0 +1,44 @@ +// -*- 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_EMPTY_H +#define _LIBCPP___ITERATOR_EMPTY_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr auto empty(const _Cont& __c) +_NOEXCEPT_(noexcept(__c.empty())) +-> decltype (__c.empty()) +{ return __c.empty(); } + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } + +template +_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY +constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_EMPTY_H diff --git a/include/__iterator/erase_if_container.h b/include/__iterator/erase_if_container.h new file mode 100644 index 000000000..08f6e2248 --- /dev/null +++ b/include/__iterator/erase_if_container.h @@ -0,0 +1,40 @@ +// -*- 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_ERASE_IF_CONTAINER_H +#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI +typename _Container::size_type +__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { + typename _Container::size_type __old_size = __c.size(); + + const typename _Container::iterator __last = __c.end(); + for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } + + return __old_size - __c.size(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H diff --git a/include/__iterator/front_insert_iterator.h b/include/__iterator/front_insert_iterator.h new file mode 100644 index 000000000..b229a99f1 --- /dev/null +++ b/include/__iterator/front_insert_iterator.h @@ -0,0 +1,70 @@ +// -*- 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_FRONT_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS front_insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_) + {container->push_front(__value_); return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_) + {container->push_front(_VSTD::move(__value_)); return *this;} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +front_insert_iterator<_Container> +front_inserter(_Container& __x) +{ + return front_insert_iterator<_Container>(__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H diff --git a/include/__iterator/incrementable_traits.h b/include/__iterator/incrementable_traits.h new file mode 100644 index 000000000..3b68acc9b --- /dev/null +++ b/include/__iterator/incrementable_traits.h @@ -0,0 +1,72 @@ +// -*- 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_INCREMENTABLE_TRAITS_H +#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [incrementable.traits] +template struct incrementable_traits {}; + +template +requires is_object_v<_Tp> +struct incrementable_traits<_Tp*> { + using difference_type = ptrdiff_t; +}; + +template +struct incrementable_traits : incrementable_traits<_Ip> {}; + +template +concept __has_member_difference_type = requires { typename _Tp::difference_type; }; + +template<__has_member_difference_type _Tp> +struct incrementable_traits<_Tp> { + using difference_type = typename _Tp::difference_type; +}; + +template +concept __has_integral_minus = + requires(const _Tp& __x, const _Tp& __y) { + { __x - __y } -> integral; + }; + +template<__has_integral_minus _Tp> +requires (!__has_member_difference_type<_Tp>) +struct incrementable_traits<_Tp> { + using difference_type = make_signed_t() - declval<_Tp>())>; +}; + +template +struct iterator_traits; + +// Let `RI` be `remove_cvref_t`. The type `iter_difference_t` denotes +// `incrementable_traits::difference_type` if `iterator_traits` names a specialization +// generated from the primary template, and `iterator_traits::difference_type` otherwise. +template +using iter_difference_t = typename conditional_t<__is_primary_template > >::value, + incrementable_traits >, + iterator_traits > >::difference_type; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H diff --git a/include/__iterator/indirectly_comparable.h b/include/__iterator/indirectly_comparable.h new file mode 100644 index 000000000..ad5ff1a86 --- /dev/null +++ b/include/__iterator/indirectly_comparable.h @@ -0,0 +1,30 @@ +// -*- 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_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept indirectly_comparable = + indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git a/include/__iterator/insert_iterator.h b/include/__iterator/insert_iterator.h new file mode 100644 index 000000000..dc617c1c9 --- /dev/null +++ b/include/__iterator/insert_iterator.h @@ -0,0 +1,81 @@ +// -*- 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_INSERT_ITERATOR_H +#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +template +using __insert_iterator_iter_t = ranges::iterator_t<_Container>; +#else +template +using __insert_iterator_iter_t = typename _Container::iterator; +#endif + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS insert_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +protected: + _Container* container; + __insert_iterator_iter_t<_Container> iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) + : container(_VSTD::addressof(__x)), iter(__i) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_) + {iter = container->insert(iter, __value_); ++iter; return *this;} +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_) + {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;} +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int) {return *this;} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +insert_iterator<_Container> +inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) +{ + return insert_iterator<_Container>(__x, __i); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H diff --git a/include/__iterator/istream_iterator.h b/include/__iterator/istream_iterator.h new file mode 100644 index 000000000..979d714ed --- /dev/null +++ b/include/__iterator/istream_iterator.h @@ -0,0 +1,92 @@ +// -*- 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_ISTREAM_ITERATOR_H +#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include // for forward declarations of char_traits and basic_istream + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template , class _Distance = ptrdiff_t> +class _LIBCPP_TEMPLATE_VIS istream_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + istream_type* __in_stream_; + _Tp __value_; +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} + _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} + _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));} + _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() + { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + return *this; + } + _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int) + {istream_iterator __t(*this); ++(*this); return __t;} + + template + friend _LIBCPP_INLINE_VISIBILITY + bool + operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, + const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) +{ + return __x.__in_stream_ == __y.__in_stream_; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) +{ + return !(__x == __y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H diff --git a/include/__iterator/istreambuf_iterator.h b/include/__iterator/istreambuf_iterator.h new file mode 100644 index 000000000..0c7676f16 --- /dev/null +++ b/include/__iterator/istreambuf_iterator.h @@ -0,0 +1,105 @@ +// -*- 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_ISTREAMBUF_ITERATOR_H +#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include // for forward declaration of basic_streambuf + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS istreambuf_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef input_iterator_tag iterator_category; + typedef _CharT value_type; + typedef typename _Traits::off_type difference_type; + typedef _CharT* pointer; + typedef _CharT reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT,_Traits> streambuf_type; + typedef basic_istream<_CharT,_Traits> istream_type; +private: + mutable streambuf_type* __sbuf_; + + class __proxy + { + char_type __keep_; + streambuf_type* __sbuf_; + _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s) + : __keep_(__c), __sbuf_(__s) {} + friend class istreambuf_iterator; + public: + _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;} + }; + + _LIBCPP_INLINE_VISIBILITY + bool __test_for_eof() const + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) + __sbuf_ = nullptr; + return __sbuf_ == nullptr; + } +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT + : __sbuf_(__p.__sbuf_) {} + + _LIBCPP_INLINE_VISIBILITY char_type operator*() const + {return static_cast(__sbuf_->sgetc());} + _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++() + { + __sbuf_->sbumpc(); + return *this; + } + _LIBCPP_INLINE_VISIBILITY __proxy operator++(int) + { + return __proxy(__sbuf_->sbumpc(), __sbuf_); + } + + _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const + {return __test_for_eof() == __b.__test_for_eof();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return __a.equal(__b);} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, + const istreambuf_iterator<_CharT,_Traits>& __b) + {return !__a.equal(__b);} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H diff --git a/include/__iterator/iter_move.h b/include/__iterator/iter_move.h new file mode 100644 index 000000000..45d9ade68 --- /dev/null +++ b/include/__iterator/iter_move.h @@ -0,0 +1,93 @@ +// -*- 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_ITER_MOVE_H +#define _LIBCPP___ITERATOR_ITER_MOVE_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/forward.h> +#include // __class_or_enum +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [iterator.cust.move] + +namespace ranges { +namespace __iter_move { + +void iter_move(); + +template +concept __unqualified_iter_move = + __class_or_enum> && + requires (_Tp&& __t) { + iter_move(_VSTD::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: +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 + requires __class_or_enum> && __unqualified_iter_move<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const + noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i)))) + { + return iter_move(_VSTD::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 + requires (!(__class_or_enum> && __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(__i))>) { + return _VSTD::move(*_VSTD::forward<_Ip>(__i)); + } else { + return *_VSTD::forward<_Ip>(__i); + } + } + + // [iterator.cust.move]/1.3 + // Otherwise, ranges::iter_move(E) is ill-formed. +}; +} // namespace __iter_move + +inline namespace __cpo { + inline constexpr auto iter_move = __iter_move::__fn{}; +} // namespace __cpo +} // namespace ranges + +template<__dereferenceable _Tp> + requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; } +using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>())); + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITER_MOVE_H diff --git a/include/__iterator/iter_swap.h b/include/__iterator/iter_swap.h new file mode 100644 index 000000000..0b290520b --- /dev/null +++ b/include/__iterator/iter_swap.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___ITERATOR_ITER_SWAP_H +#define _LIBCPP___ITERATOR_ITER_SWAP_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [iter.cust.swap] + +namespace ranges { +namespace __iter_swap { + template + void iter_swap(_I1, _I2) = delete; + + template + concept __unqualified_iter_swap = + (__class_or_enum> || __class_or_enum>) && + requires (_T1&& __x, _T2&& __y) { + iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + }; + + template + concept __readable_swappable = + indirectly_readable<_T1> && indirectly_readable<_T2> && + swappable_with, iter_reference_t<_T2>>; + + struct __fn { + template + requires __unqualified_iter_swap<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)))) + { + (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + } + + template + requires (!__unqualified_iter_swap<_T1, _T2>) && + __readable_swappable<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)))) + { + ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)); + } + + template + requires (!__unqualified_iter_swap<_T1, _T2> && + !__readable_swappable<_T1, _T2>) && + indirectly_movable_storable<_T1, _T2> && + indirectly_movable_storable<_T2, _T1> + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && + noexcept(*__y = ranges::iter_move(__x)) && + noexcept(*_VSTD::forward<_T1>(__x) = declval>())) + { + iter_value_t<_T2> __old(ranges::iter_move(__y)); + *__y = ranges::iter_move(__x); + *_VSTD::forward<_T1>(__x) = _VSTD::move(__old); + } + }; +} // namespace __iter_swap + +inline namespace __cpo { + inline constexpr auto iter_swap = __iter_swap::__fn{}; +} // namespace __cpo +} // namespace ranges + +template +concept indirectly_swappable = + indirectly_readable<_I1> && indirectly_readable<_I2> && + requires(const _I1 __i1, const _I2 __i2) { + ranges::iter_swap(__i1, __i1); + ranges::iter_swap(__i2, __i2); + ranges::iter_swap(__i1, __i2); + ranges::iter_swap(__i2, __i1); + }; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITER_SWAP_H diff --git a/include/__iterator/iterator.h b/include/__iterator/iterator.h new file mode 100644 index 000000000..be298ee52 --- /dev/null +++ b/include/__iterator/iterator.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_ITERATOR_H +#define _LIBCPP___ITERATOR_ITERATOR_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator +{ + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + typedef _Category iterator_category; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITERATOR_H diff --git a/include/__iterator/iterator_traits.h b/include/__iterator/iterator_traits.h new file mode 100644 index 000000000..f2dbb7c70 --- /dev/null +++ b/include/__iterator/iterator_traits.h @@ -0,0 +1,495 @@ +// -*- 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_ITERATOR_TRAITS_H +#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H + +#include <__config> +#include <__iterator/incrementable_traits.h> +#include <__iterator/readable_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +using __with_reference = _Tp&; + +template +concept __referenceable = requires { + typename __with_reference<_Tp>; +}; + +template +concept __dereferenceable = requires(_Tp& __t) { + { *__t } -> __referenceable; // not required to be equality-preserving +}; + +// [iterator.traits] +template<__dereferenceable _Tp> +using iter_reference_t = decltype(*declval<_Tp&>()); + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +struct _LIBCPP_TEMPLATE_VIS iterator_traits; + +struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; +#if _LIBCPP_STD_VER > 17 +struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; +#endif + +template +struct __iter_traits_cache { + using type = _If< + __is_primary_template >::value, + _Iter, + iterator_traits<_Iter> + >; +}; +template +using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; + +struct __iter_concept_concept_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept; +}; +struct __iter_concept_category_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category; +}; +struct __iter_concept_random_fallback { + template + using _Apply = __enable_if_t< + __is_primary_template >::value, + random_access_iterator_tag + >; +}; + +template struct __test_iter_concept + : _IsValidExpansion<_Tester::template _Apply, _Iter>, + _Tester +{ +}; + +template +struct __iter_concept_cache { + using type = _Or< + __test_iter_concept<_Iter, __iter_concept_concept_test>, + __test_iter_concept<_Iter, __iter_concept_category_test>, + __test_iter_concept<_Iter, __iter_concept_random_fallback> + >; +}; + +template +using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; + + +template +struct __has_iterator_typedefs +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename __void_t::type* = 0, + typename __void_t::type* = 0, + typename __void_t::type* = 0, + typename __void_t::type* = 0, + typename __void_t::type* = 0); +public: + static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1; +}; + + +template +struct __has_iterator_category +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::iterator_category* = nullptr); +public: + static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; +}; + +template +struct __has_iterator_concept +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::iterator_concept* = nullptr); +public: + static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; +}; + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// 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. +namespace __iterator_traits_detail { +template +concept __cpp17_iterator = + requires(_Ip __i) { + { *__i } -> __referenceable; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __referenceable; + } && + copyable<_Ip>; + +template +concept __cpp17_input_iterator = + __cpp17_iterator<_Ip> && + equality_comparable<_Ip> && + requires(_Ip __i) { + typename incrementable_traits<_Ip>::difference_type; + typename indirectly_readable_traits<_Ip>::value_type; + typename common_reference_t&&, + typename indirectly_readable_traits<_Ip>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; + }; + +template +concept __cpp17_forward_iterator = + __cpp17_input_iterator<_Ip> && + constructible_from<_Ip> && + is_lvalue_reference_v> && + same_as>, + typename indirectly_readable_traits<_Ip>::value_type> && + requires(_Ip __i) { + { __i++ } -> convertible_to<_Ip const&>; + { *__i++ } -> same_as>; + }; + +template +concept __cpp17_bidirectional_iterator = + __cpp17_forward_iterator<_Ip> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; + }; + +template +concept __cpp17_random_access_iterator = + __cpp17_bidirectional_iterator<_Ip> && + totally_ordered<_Ip> && + requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { + { __i += __n } -> same_as<_Ip&>; + { __i -= __n } -> same_as<_Ip&>; + { __i + __n } -> same_as<_Ip>; + { __n + __i } -> same_as<_Ip>; + { __i - __n } -> same_as<_Ip>; + { __i - __i } -> same_as; + { __i[__n] } -> convertible_to>; + }; +} // namespace __iterator_traits_detail + +template +concept __has_member_reference = requires { typename _Ip::reference; }; + +template +concept __has_member_pointer = requires { typename _Ip::pointer; }; + +template +concept __has_member_iterator_category = requires { typename _Ip::iterator_category; }; + +template +concept __specifies_members = requires { + typename _Ip::value_type; + typename _Ip::difference_type; + requires __has_member_reference<_Ip>; + requires __has_member_iterator_category<_Ip>; + }; + +template +struct __iterator_traits_member_pointer_or_void { + using type = void; +}; + +template<__has_member_pointer _Tp> +struct __iterator_traits_member_pointer_or_void<_Tp> { + using type = typename _Tp::pointer; +}; + +template +concept __cpp17_iterator_missing_members = + !__specifies_members<_Tp> && + __iterator_traits_detail::__cpp17_iterator<_Tp>; + +template +concept __cpp17_input_iterator_missing_members = + __cpp17_iterator_missing_members<_Tp> && + __iterator_traits_detail::__cpp17_input_iterator<_Tp>; + +// Otherwise, `pointer` names `void`. +template +struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; }; + +// [iterator.traits]/3.2.1 +// If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type. +template<__has_member_pointer _Ip> +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; }; + +// Otherwise, if `decltype(declval().operator->())` is well-formed, then `pointer` names that +// type. +template + requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>) +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { + using type = decltype(declval<_Ip&>().operator->()); +}; + +// Otherwise, `reference` names `iter-reference-t`. +template +struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; }; + +// [iterator.traits]/3.2.2 +// If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type. +template<__has_member_reference _Ip> +struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; }; + +// [iterator.traits]/3.2.3.4 +// input_iterator_tag +template +struct __deduce_iterator_category { + using type = input_iterator_tag; +}; + +// [iterator.traits]/3.2.3.1 +// `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = random_access_iterator_tag; +}; + +// [iterator.traits]/3.2.3.2 +// `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = bidirectional_iterator_tag; +}; + +// [iterator.traits]/3.2.3.3 +// `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise +template<__iterator_traits_detail::__cpp17_forward_iterator _Ip> +struct __deduce_iterator_category<_Ip> { + using type = forward_iterator_tag; +}; + +template +struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {}; + +// [iterator.traits]/3.2.3 +// If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names +// that type. +template<__has_member_iterator_category _Ip> +struct __iterator_traits_iterator_category<_Ip> { + using type = typename _Ip::iterator_category; +}; + +// otherwise, it names void. +template +struct __iterator_traits_difference_type { using type = void; }; + +// If the qualified-id `incrementable_traits::difference_type` is valid and denotes a type, then +// `difference_type` names that type; +template +requires requires { typename incrementable_traits<_Ip>::difference_type; } +struct __iterator_traits_difference_type<_Ip> { + using type = typename incrementable_traits<_Ip>::difference_type; +}; + +// [iterator.traits]/3.4 +// Otherwise, `iterator_traits` has no members by any of the above names. +template +struct __iterator_traits {}; + +// [iterator.traits]/3.1 +// If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and +// `iterator-category`, then `iterator-traits` has the following publicly accessible members: +template<__specifies_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename _Ip::iterator_category; + using value_type = typename _Ip::value_type; + using difference_type = typename _Ip::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; + using reference = typename _Ip::reference; +}; + +// [iterator.traits]/3.2 +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`, +// `iterator-traits` has the following publicly accessible members: +template<__cpp17_input_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type; + using value_type = typename indirectly_readable_traits<_Ip>::value_type; + using difference_type = typename incrementable_traits<_Ip>::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_arrow_or_void<_Ip>::type; + using reference = typename __iterator_traits_member_reference<_Ip>::type; +}; + +// Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then +// `iterator_traits` has the following publicly accessible members: +template<__cpp17_iterator_missing_members _Ip> +struct __iterator_traits<_Ip> { + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = typename __iterator_traits_difference_type<_Ip>::type; + using pointer = void; + using reference = void; +}; + +template +struct iterator_traits : __iterator_traits<_Ip> { + using __primary_template = iterator_traits; +}; + +#else // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template struct __iterator_traits {}; + +template struct __iterator_traits_impl {}; + +template +struct __iterator_traits_impl<_Iter, true> +{ + typedef typename _Iter::difference_type difference_type; + typedef typename _Iter::value_type value_type; + typedef typename _Iter::pointer pointer; + typedef typename _Iter::reference reference; + typedef typename _Iter::iterator_category iterator_category; +}; + +template +struct __iterator_traits<_Iter, true> + : __iterator_traits_impl + < + _Iter, + is_convertible::value || + is_convertible::value + > +{}; + +// iterator_traits will only have the nested types if Iterator::iterator_category +// exists. Else iterator_traits will be an empty class. This is a +// conforming extension which allows some programs to compile and behave as +// the client expects instead of failing at compile time. + +template +struct _LIBCPP_TEMPLATE_VIS iterator_traits + : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { + + using __primary_template = iterator_traits; +}; +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +requires is_object_v<_Tp> +#endif +struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> +{ + typedef ptrdiff_t difference_type; + typedef typename remove_cv<_Tp>::type value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef random_access_iterator_tag iterator_category; +#if _LIBCPP_STD_VER > 17 + typedef contiguous_iterator_tag iterator_concept; +#endif +}; + +template >::value> +struct __has_iterator_category_convertible_to + : is_convertible::iterator_category, _Up> +{}; + +template +struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {}; + +template ::value> +struct __has_iterator_concept_convertible_to + : is_convertible +{}; + +template +struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; + +template +struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; + +template +struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; + +template +struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; + +template +struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; + +// __is_cpp17_contiguous_iterator determines if an iterator is known by +// libc++ to be contiguous, either because it advertises itself as such +// (in C++20) or because it is a pointer type or a known trivial wrapper +// around a (possibly fancy) pointer type, such as __wrap_iter. +// Such iterators receive special "contiguous" optimizations in +// std::copy and std::sort. +// +#if _LIBCPP_STD_VER > 17 +template +struct __is_cpp17_contiguous_iterator : _Or< + __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, + __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> +> {}; +#else +template +struct __is_cpp17_contiguous_iterator : false_type {}; +#endif + +// Any native pointer which is an iterator is also a contiguous iterator. +template +struct __is_cpp17_contiguous_iterator<_Up*> : true_type {}; + + +template +struct __is_exactly_cpp17_input_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; + +#if _LIBCPP_STD_VER >= 17 +template +using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; + +template +using __iter_key_type = remove_const_t::value_type::first_type>; + +template +using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; + +template +using __iter_to_alloc_type = pair< + add_const_t::value_type::first_type>, + typename iterator_traits<_InputIterator>::value_type::second_type>; +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H diff --git a/include/__iterator/move_iterator.h b/include/__iterator/move_iterator.h new file mode 100644 index 000000000..29bac864c --- /dev/null +++ b/include/__iterator/move_iterator.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___ITERATOR_MOVE_ITERATOR_H +#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS move_iterator +{ +public: +#if _LIBCPP_STD_VER > 17 + typedef input_iterator_tag iterator_concept; +#endif + + 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; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef iterator_type pointer; + +#ifndef _LIBCPP_CXX03_LANG + typedef typename iterator_traits::reference __reference; + typedef typename conditional< + is_reference<__reference>::value, + typename remove_reference<__reference>::type&&, + __reference + >::type reference; +#else + typedef typename iterator_traits::reference reference; +#endif + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator() : __current_() {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {} + + template ::value && is_convertible::value + > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template ::value && + is_convertible::value && + is_assignable<_Iter&, const _Up&>::value + > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + _Iter base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const { return static_cast(*__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(__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; } + _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; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + +private: + _Iter __current_; +}; + +template +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(); +} + +template +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(); +} + +template +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(); +} + +template +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(); +} + +template +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(); +} + +template +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(); +} + +#ifndef _LIBCPP_CXX03_LANG +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> decltype(__x.base() - __y.base()) +{ + return __x.base() - __y.base(); +} +#else +template +inline _LIBCPP_HIDE_FROM_ABI +typename move_iterator<_Iter1>::difference_type +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +{ + return __x.base() - __y.base(); +} +#endif + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +move_iterator<_Iter> +operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) +{ + return move_iterator<_Iter>(__x.base() + __n); +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +move_iterator<_Iter> +make_move_iterator(_Iter __i) +{ + return move_iterator<_Iter>(_VSTD::move(__i)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H diff --git a/include/__iterator/next.h b/include/__iterator/next.h new file mode 100644 index 000000000..5dda0674d --- /dev/null +++ b/include/__iterator/next.h @@ -0,0 +1,86 @@ +// -*- 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_NEXT_H +#define _LIBCPP___ITERATOR_NEXT_H + +#include <__config> +#include <__debug> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); + + _VSTD::advance(__x, __n); + return __x; +} + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +// [range.iter.op.next] + +namespace ranges { +namespace __next { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x) const { + ++__x; + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + ranges::advance(__x, __n); + return __x; + } + + template _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, _Sp __bound) const { + ranges::advance(__x, __bound); + return __x; + } + + template _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const { + ranges::advance(__x, __n, __bound); + return __x; + } +}; + +} // namespace __next + +inline namespace __cpo { + inline constexpr auto next = __next::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_NEXT_H diff --git a/include/__iterator/ostream_iterator.h b/include/__iterator/ostream_iterator.h new file mode 100644 index 000000000..20a36742c --- /dev/null +++ b/include/__iterator/ostream_iterator.h @@ -0,0 +1,70 @@ +// -*- 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_OSTREAM_ITERATOR_H +#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include // for forward declarations of char_traits and basic_ostream + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template > +class _LIBCPP_TEMPLATE_VIS ostream_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + +private: + ostream_type* __out_stream_; + const char_type* __delim_; +public: + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT + : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT + : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) + { + *__out_stream_ << __value_; + if (__delim_) + *__out_stream_ << __delim_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H diff --git a/include/__iterator/ostreambuf_iterator.h b/include/__iterator/ostreambuf_iterator.h new file mode 100644 index 000000000..3272f6c99 --- /dev/null +++ b/include/__iterator/ostreambuf_iterator.h @@ -0,0 +1,76 @@ +// -*- 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_OSTREAMBUF_ITERATOR_H +#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H + +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include // for forward declaration of basic_streambuf + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER > 17 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + +private: + streambuf_type* __sbuf_; +public: + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT + : __sbuf_(__s.rdbuf()) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT + : __sbuf_(__s) {} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c) + { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) + __sbuf_ = nullptr; + return *this; + } + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;} + _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;} + + template + friend + _LIBCPP_HIDDEN + ostreambuf_iterator<_Ch, _Tr> + __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, + const _Ch* __ob, const _Ch* __op, const _Ch* __oe, + ios_base& __iob, _Ch __fl); +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H diff --git a/include/__iterator/prev.h b/include/__iterator/prev.h new file mode 100644 index 000000000..2b8c15fe5 --- /dev/null +++ b/include/__iterator/prev.h @@ -0,0 +1,78 @@ +// -*- 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_PREV_H +#define _LIBCPP___ITERATOR_PREV_H + +#include <__config> +#include <__debug> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type + prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); + _VSTD::advance(__x, -__n); + return __x; +} + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +// [range.iter.op.prev] + +namespace ranges { +namespace __prev { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x) const { + --__x; + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + ranges::advance(__x, -__n); + return __x; + } + + template + _LIBCPP_HIDE_FROM_ABI + constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const { + ranges::advance(__x, -__n, __bound); + return __x; + } +}; + +} // namespace __prev + +inline namespace __cpo { + inline constexpr auto prev = __prev::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PREV_H diff --git a/include/__iterator/projected.h b/include/__iterator/projected.h new file mode 100644 index 000000000..30ea3a124 --- /dev/null +++ b/include/__iterator/projected.h @@ -0,0 +1,40 @@ +// -*- 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_PROJECTED_H +#define _LIBCPP___ITERATOR_PROJECTED_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template _Proj> +struct projected { + using value_type = remove_cvref_t>; + indirect_result_t<_Proj&, _It> operator*() const; // not defined +}; + +template +struct incrementable_traits> { + using difference_type = iter_difference_t<_It>; +}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PROJECTED_H diff --git a/include/__iterator/readable_traits.h b/include/__iterator/readable_traits.h new file mode 100644 index 000000000..c0b16bafd --- /dev/null +++ b/include/__iterator/readable_traits.h @@ -0,0 +1,86 @@ +// -*- 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_READABLE_TRAITS_H +#define _LIBCPP___ITERATOR_READABLE_TRAITS_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// [readable.traits] +template struct __cond_value_type {}; + +template +requires is_object_v<_Tp> +struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; + +template +concept __has_member_value_type = requires { typename _Tp::value_type; }; + +template +concept __has_member_element_type = requires { typename _Tp::element_type; }; + +template struct indirectly_readable_traits {}; + +template +requires is_array_v<_Ip> +struct indirectly_readable_traits<_Ip> { + using value_type = remove_cv_t>; +}; + +template +struct indirectly_readable_traits : indirectly_readable_traits<_Ip> {}; + +template +struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; + +template<__has_member_value_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template<__has_member_element_type _Tp> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template<__has_member_value_type _Tp> + requires __has_member_element_type<_Tp> +struct indirectly_readable_traits<_Tp> {}; + +template<__has_member_value_type _Tp> + requires __has_member_element_type<_Tp> && + same_as, + remove_cv_t> +struct indirectly_readable_traits<_Tp> + : __cond_value_type {}; + +template +struct iterator_traits; + +// Let `RI` be `remove_cvref_t`. The type `iter_value_t` denotes +// `indirectly_readable_traits::value_type` if `iterator_traits` names a specialization +// generated from the primary template, and `iterator_traits::value_type` otherwise. +template +using iter_value_t = typename conditional_t<__is_primary_template > >::value, + indirectly_readable_traits >, + iterator_traits > >::value_type; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H diff --git a/include/__iterator/reverse_access.h b/include/__iterator/reverse_access.h new file mode 100644 index 000000000..643aede01 --- /dev/null +++ b/include/__iterator/reverse_access.h @@ -0,0 +1,104 @@ +// -*- 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_REVERSE_ACCESS_H +#define _LIBCPP___ITERATOR_REVERSE_ACCESS_H + +#include <__config> +#include <__iterator/reverse_iterator.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_CXX03_LANG) + +#if _LIBCPP_STD_VER > 11 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array + _Np); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) +{ + return reverse_iterator<_Tp*>(__array); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator rbegin(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.end()); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator rend(initializer_list<_Ep> __il) +{ + return reverse_iterator(__il.begin()); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) +{ + return __c.rbegin(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto rend(_Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto rend(const _Cp& __c) -> decltype(__c.rend()) +{ + return __c.rend(); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) +{ + return _VSTD::rbegin(__c); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) +{ + return _VSTD::rend(__c); +} + +#endif + +#endif // !defined(_LIBCPP_CXX03_LANG) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H diff --git a/include/__iterator/reverse_iterator.h b/include/__iterator/reverse_iterator.h new file mode 100644 index 000000000..af855a0a1 --- /dev/null +++ b/include/__iterator/reverse_iterator.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___ITERATOR_REVERSE_ITERATOR_H +#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H + +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__iterator/iterator.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +class _LIBCPP_TEMPLATE_VIS reverse_iterator +#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) + : public iterator::iterator_category, + typename iterator_traits<_Iter>::value_type, + typename iterator_traits<_Iter>::difference_type, + typename iterator_traits<_Iter>::pointer, + typename iterator_traits<_Iter>::reference> +#endif +{ +_LIBCPP_SUPPRESS_DEPRECATED_POP +private: +#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES + _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break +#endif + +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; + +#if _LIBCPP_STD_VER > 17 + typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + bidirectional_iterator_tag> iterator_concept; +#endif + +#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator() : __t(), current() {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator(const reverse_iterator<_Up>& __u) + : __t(__u.base()), current(__u.base()) + { } + + template ::value && + is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + __t = current = __u.base(); + return *this; + } +#else + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator() : current() {} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit reverse_iterator(_Iter __x) : current(__x) {} + + template ::value && is_convertible<_Up const&, _Iter>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator(const reverse_iterator<_Up>& __u) + : current(__u.base()) + { } + + template ::value && + is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value + > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + current = __u.base(); + return *this; + } +#endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _Iter base() const {return current;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const {return _VSTD::addressof(operator*());} + _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;} + _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;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + 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);} + _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);} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() > __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() != __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() < __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() <= __y.base(); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +bool +operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __x.base() >= __y.base(); +} + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +template _Iter2> +_LIBCPP_HIDE_FROM_ABI constexpr +compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() <=> __x.base(); +} +#endif + +#ifndef _LIBCPP_CXX03_LANG +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +auto +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +-> decltype(__y.base() - __x.base()) +{ + return __y.base() - __x.base(); +} +#else +template +inline _LIBCPP_INLINE_VISIBILITY +typename reverse_iterator<_Iter1>::difference_type +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() - __x.base(); +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator<_Iter> +operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) +{ + return reverse_iterator<_Iter>(__x.base() - __n); +} + +#if _LIBCPP_STD_VER > 11 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) +{ + return reverse_iterator<_Iter>(__i); +} +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H diff --git a/include/__iterator/size.h b/include/__iterator/size.h new file mode 100644 index 000000000..2e6a7d386 --- /dev/null +++ b/include/__iterator/size.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___ITERATOR_SIZE_H +#define _LIBCPP___ITERATOR_SIZE_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +template +_LIBCPP_INLINE_VISIBILITY +constexpr auto size(const _Cont& __c) +_NOEXCEPT_(noexcept(__c.size())) +-> decltype (__c.size()) +{ return __c.size(); } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; } + +#if _LIBCPP_STD_VER > 17 +template +_LIBCPP_INLINE_VISIBILITY +constexpr auto ssize(const _Cont& __c) +_NOEXCEPT_(noexcept(static_cast>>(__c.size()))) +-> common_type_t> +{ return static_cast>>(__c.size()); } + +template +_LIBCPP_INLINE_VISIBILITY +constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; } +#endif + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_SIZE_H diff --git a/include/__iterator/unreachable_sentinel.h b/include/__iterator/unreachable_sentinel.h new file mode 100644 index 000000000..b200236d8 --- /dev/null +++ b/include/__iterator/unreachable_sentinel.h @@ -0,0 +1,38 @@ +// -*- 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_UNREACHABLE_SENTINEL_H +#define _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H + +#include <__config> +#include <__iterator/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +struct unreachable_sentinel_t { + template + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(unreachable_sentinel_t, const _Iter&) noexcept { + return false; + } +}; + +inline constexpr unreachable_sentinel_t unreachable_sentinel{}; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H diff --git a/include/__iterator/wrap_iter.h b/include/__iterator/wrap_iter.h new file mode 100644 index 000000000..d9dbee588 --- /dev/null +++ b/include/__iterator/wrap_iter.h @@ -0,0 +1,285 @@ +// -*- 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_WRAP_ITER_H +#define _LIBCPP___ITERATOR_WRAP_ITER_H + +#include <__config> +#include <__debug> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/pointer_traits.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __wrap_iter +{ +public: + typedef _Iter iterator_type; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef typename iterator_traits::pointer pointer; + typedef typename iterator_traits::reference reference; + typedef typename iterator_traits::iterator_category iterator_category; +#if _LIBCPP_STD_VER > 17 + typedef contiguous_iterator_tag iterator_concept; +#endif + +private: + iterator_type __i; +public: + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter() _NOEXCEPT + : __i() + { + _VSTD::__debug_db_insert_i(this); + } + template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + __wrap_iter(const __wrap_iter<_Up>& __u, + typename enable_if::value>::type* = nullptr) _NOEXCEPT + : __i(__u.base()) + { +#if _LIBCPP_DEBUG_LEVEL == 2 + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__u)); +#endif + } +#if _LIBCPP_DEBUG_LEVEL == 2 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + __wrap_iter(const __wrap_iter& __x) + : __i(__x.base()) + { + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + __wrap_iter& operator=(const __wrap_iter& __x) + { + if (this != _VSTD::addressof(__x)) + { + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); + __i = __x.__i; + } + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 + ~__wrap_iter() + { + if (!__libcpp_is_constant_evaluated()) + __get_db()->__erase_i(this); + } +#endif + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); + return *__i; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); + return _VSTD::__to_address(__i); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator++() _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment a non-incrementable iterator"); + ++__i; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator++(int) _NOEXCEPT + {__wrap_iter __tmp(*this); ++(*this); return __tmp;} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator--() _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement a non-decrementable iterator"); + --__i; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator--(int) _NOEXCEPT + {__wrap_iter __tmp(*this); --(*this); return __tmp;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator+ (difference_type __n) const _NOEXCEPT + {__wrap_iter __w(*this); __w += __n; return __w;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n), + "Attempted to add/subtract an iterator outside its valid range"); + __i += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter operator- (difference_type __n) const _NOEXCEPT + {return *this + (-__n);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator-=(difference_type __n) _NOEXCEPT + {*this += -__n; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT + { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n), + "Attempted to subscript an iterator outside its valid range"); + return __i[__n]; + } + + _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) + { + 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 friend class __wrap_iter; + template friend class basic_string; + template friend class _LIBCPP_TEMPLATE_VIS vector; + template friend class _LIBCPP_TEMPLATE_VIS span; +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return __x.base() == __y.base(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return __x.base() == __y.base(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to compare incomparable iterators"); + return __x.base() < __y.base(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); + return __x.base() < __y.base(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__x == __y); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__x == __y); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return __y < __x; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return __y < __x; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__x < __y); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__x < __y); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +{ + return !(__y < __x); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +{ + return !(__y < __x); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +#ifndef _LIBCPP_CXX03_LANG +auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + -> decltype(__x.base() - __y.base()) +#else +typename __wrap_iter<_Iter1>::difference_type +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +#endif // C++03 +{ + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), + "Attempted to subtract incompatible iterators"); + return __x.base() - __y.base(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 +__wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, __wrap_iter<_Iter1> __x) _NOEXCEPT +{ + __x += __n; + return __x; +} + +#if _LIBCPP_STD_VER <= 17 +template +struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; +#endif + +template +struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > +{ + typedef __wrap_iter<_It> pointer; + typedef typename pointer_traits<_It>::element_type element_type; + typedef typename pointer_traits<_It>::difference_type difference_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + static element_type *to_address(pointer __w) _NOEXCEPT { + return _VSTD::__to_address(__w.base()); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_WRAP_ITER_H diff --git a/include/__libcpp_version b/include/__libcpp_version index 5caff40c4..bfed81939 100644 --- a/include/__libcpp_version +++ b/include/__libcpp_version @@ -1 +1 @@ -10000 +14000 diff --git a/include/__locale b/include/__locale index 2b6982fc6..51f35eece 100644 --- a/include/__locale +++ b/include/__locale @@ -10,36 +10,40 @@ #ifndef _LIBCPP___LOCALE #define _LIBCPP___LOCALE +#include <__availability> #include <__config> -#include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include + #if defined(_LIBCPP_MSVCRT_LIKE) # include -# include -#elif defined(_AIX) -# include +# include <__support/win32/locale_win32.h> +#elif defined(_AIX) || defined(__MVS__) +# include <__support/ibm/xlocale.h> #elif defined(__ANDROID__) -# include +# include <__support/android/locale_bionic.h> #elif defined(__sun__) # include -# include +# include <__support/solaris/xlocale.h> #elif defined(_NEWLIB_VERSION) -# include +# include <__support/newlib/xlocale.h> +#elif defined(__OpenBSD__) +# include <__support/openbsd/xlocale.h> #elif (defined(__APPLE__) || defined(__FreeBSD__) \ || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) # include #elif defined(__Fuchsia__) -# include +# include <__support/fuchsia/xlocale.h> #elif defined(__wasi__) // WASI libc uses musl's locales support. -# include +# include <__support/musl/xlocale.h> #elif defined(_LIBCPP_HAS_MUSL_LIBC) -# include +# include <__support/musl/xlocale.h> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -76,7 +80,7 @@ struct __libcpp_locale_guard { // locale name, otherwise it will be a semicolon-separated string listing // each category. In the second case, we know at least one category won't // be what we want, so we only have to check the first case. - if (strcmp(__l.__get_locale(), __lc) != 0) { + if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) { __locale_all = _strdup(__lc); if (__locale_all == nullptr) __throw_bad_alloc(); @@ -105,7 +109,6 @@ struct __libcpp_locale_guard { }; #endif - class _LIBCPP_TYPE_VIS locale; template @@ -206,10 +209,11 @@ class _LIBCPP_TYPE_VIS locale::id static int32_t __next_id; public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} + void operator=(const id&) = delete; + id(const id&) = delete; + private: void __init(); - void operator=(const id&); // = delete; - id(const id&); // = delete; public: // only needed for tests long __get(); @@ -335,8 +339,10 @@ collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const return static_cast(__h); } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate) +#endif // template class collate_byname; @@ -361,6 +367,7 @@ protected: virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; }; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS collate_byname : public collate @@ -380,6 +387,7 @@ protected: const char_type* __lo2, const char_type* __hi2) const; virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; }; +#endif template bool @@ -396,7 +404,26 @@ locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, class _LIBCPP_TYPE_VIS ctype_base { public: -#if defined(__GLIBC__) +#if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE) + typedef unsigned long mask; + static const mask space = 1<<0; + static const mask print = 1<<1; + static const mask cntrl = 1<<2; + static const mask upper = 1<<3; + static const mask lower = 1<<4; + static const mask alpha = 1<<5; + static const mask digit = 1<<6; + static const mask punct = 1<<7; + static const mask xdigit = 1<<8; + static const mask blank = 1<<9; +#if defined(__BIONIC__) + // Historically this was a part of regex_traits rather than ctype_base. The + // historical value of the constant is preserved for ABI compatibility. + static const mask __regex_word = 0x8000; +#else + static const mask __regex_word = 1<<10; +#endif // defined(__BIONIC__) +#elif defined(__GLIBC__) typedef unsigned short mask; static const mask space = _ISspace; static const mask print = _ISprint; @@ -425,7 +452,7 @@ public: static const mask punct = _PUNCT; static const mask xdigit = _HEX; static const mask blank = _BLANK; - static const mask __regex_word = 0x80; + static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) # ifdef __APPLE__ @@ -484,28 +511,51 @@ public: # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#elif defined(__MVS__) +# if defined(__NATIVE_ASCII_F) + typedef unsigned int mask; + static const mask space = _ISSPACE_A; + static const mask print = _ISPRINT_A; + static const mask cntrl = _ISCNTRL_A; + static const mask upper = _ISUPPER_A; + static const mask lower = _ISLOWER_A; + static const mask alpha = _ISALPHA_A; + static const mask digit = _ISDIGIT_A; + static const mask punct = _ISPUNCT_A; + static const mask xdigit = _ISXDIGIT_A; + static const mask blank = _ISBLANK_A; +# else + typedef unsigned short mask; + static const mask space = __ISSPACE; + static const mask print = __ISPRINT; + static const mask cntrl = __ISCNTRL; + static const mask upper = __ISUPPER; + static const mask lower = __ISLOWER; + static const mask alpha = __ISALPHA; + static const mask digit = __ISDIGIT; + static const mask punct = __ISPUNCT; + static const mask xdigit = __ISXDIGIT; + static const mask blank = __ISBLANK; +# endif + static const mask __regex_word = 0x8000; #else - typedef unsigned long mask; - static const mask space = 1<<0; - static const mask print = 1<<1; - static const mask cntrl = 1<<2; - static const mask upper = 1<<3; - static const mask lower = 1<<4; - static const mask alpha = 1<<5; - static const mask digit = 1<<6; - static const mask punct = 1<<7; - static const mask xdigit = 1<<8; - static const mask blank = 1<<9; - static const mask __regex_word = 1<<10; +# error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? #endif static const mask alnum = alpha | digit; static const mask graph = alnum | punct; _LIBCPP_INLINE_VISIBILITY ctype_base() {} + +// TODO: Remove the ifndef when the assert no longer fails on AIX. +#ifndef _AIX + static_assert((__regex_word & ~(space | print | cntrl | upper | lower | alpha | digit | punct | xdigit | blank)) == __regex_word, + "__regex_word can't overlap other bits"); +#endif }; template class _LIBCPP_TEMPLATE_VIS ctype; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS ctype : public locale::facet, @@ -607,6 +657,7 @@ protected: virtual char do_narrow(char_type, char __dfault) const; virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS ctype @@ -617,7 +668,7 @@ class _LIBCPP_TYPE_VIS ctype public: typedef char char_type; - explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); + explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0); _LIBCPP_INLINE_VISIBILITY bool is(mask __m, char_type __c) const @@ -716,6 +767,10 @@ public: static const short* __classic_upper_table() _NOEXCEPT; static const short* __classic_lower_table() _NOEXCEPT; #endif +#if defined(__MVS__) + static const unsigned short* __classic_upper_table() _NOEXCEPT; + static const unsigned short* __classic_lower_table() _NOEXCEPT; +#endif protected: ~ctype(); @@ -751,6 +806,7 @@ protected: virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; }; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS ctype_byname : public ctype @@ -776,6 +832,7 @@ protected: virtual char do_narrow(char_type, char __dfault) const; virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS template inline _LIBCPP_INLINE_VISIBILITY @@ -982,6 +1039,7 @@ protected: // template <> class codecvt +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS codecvt : public locale::facet, @@ -1062,11 +1120,12 @@ protected: virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; virtual int do_max_length() const _NOEXCEPT; }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -// template <> class codecvt +// template <> class codecvt // deprecated in C++20 template <> -class _LIBCPP_TYPE_VIS codecvt +class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt : public locale::facet, public codecvt_base { @@ -1149,10 +1208,100 @@ protected: virtual int do_max_length() const _NOEXCEPT; }; -// template <> class codecvt +#ifndef _LIBCPP_HAS_NO_CHAR8_T + +// template <> class codecvt // C++20 template <> -class _LIBCPP_TYPE_VIS codecvt +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char16_t intern_type; + typedef char8_t extern_type; + typedef mbstate_t state_type; + + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +#endif + +// template <> class codecvt // deprecated in C++20 + +template <> +class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt : public locale::facet, public codecvt_base { @@ -1235,6 +1384,96 @@ protected: virtual int do_max_length() const _NOEXCEPT; }; +#ifndef _LIBCPP_HAS_NO_CHAR8_T + +// template <> class codecvt // C++20 + +template <> +class _LIBCPP_TYPE_VIS codecvt + : public locale::facet, + public codecvt_base +{ +public: + typedef char32_t intern_type; + typedef char8_t extern_type; + typedef mbstate_t state_type; + + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(size_t __refs = 0) + : locale::facet(__refs) {} + + _LIBCPP_INLINE_VISIBILITY + result out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const + { + return do_unshift(__st, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + result in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const + { + return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); + } + + _LIBCPP_INLINE_VISIBILITY + int encoding() const _NOEXCEPT + { + return do_encoding(); + } + + _LIBCPP_INLINE_VISIBILITY + bool always_noconv() const _NOEXCEPT + { + return do_always_noconv(); + } + + _LIBCPP_INLINE_VISIBILITY + int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const + { + return do_length(__st, __frm, __end, __mx); + } + + _LIBCPP_INLINE_VISIBILITY + int max_length() const _NOEXCEPT + { + return do_max_length(); + } + + static locale::id id; + +protected: + _LIBCPP_INLINE_VISIBILITY + explicit codecvt(const char*, size_t __refs = 0) + : locale::facet(__refs) {} + + ~codecvt(); + + virtual result do_out(state_type& __st, + const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual result do_in(state_type& __st, + const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, + intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; + virtual result do_unshift(state_type& __st, + extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; + virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; + virtual int do_max_length() const _NOEXCEPT; +}; + +#endif + // template class codecvt_byname template @@ -1252,15 +1491,23 @@ protected: ~codecvt_byname(); }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() { } +_LIBCPP_SUPPRESS_DEPRECATED_POP -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) +#endif +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) // deprecated in C++20 +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) // 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) // C++20 +_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname) // C++20 +#endif template struct __narrow_to_utf8 @@ -1284,14 +1531,16 @@ struct __narrow_to_utf8<8> } }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> -struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> +struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16> : public codecvt { _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt(1) {} +_LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); + ~__narrow_to_utf8(); template _LIBCPP_INLINE_VISIBILITY @@ -1318,14 +1567,16 @@ struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> } }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> -struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> +struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32> : public codecvt { _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt(1) {} +_LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); + ~__narrow_to_utf8(); template _LIBCPP_INLINE_VISIBILITY @@ -1374,14 +1625,16 @@ struct __widen_from_utf8<8> } }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> -struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> +struct _LIBCPP_TYPE_VIS __widen_from_utf8<16> : public codecvt { _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt(1) {} +_LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); + ~__widen_from_utf8(); template _LIBCPP_INLINE_VISIBILITY @@ -1401,21 +1654,23 @@ struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> if (__r == codecvt_base::error || __nn == __nb) __throw_runtime_error("locale not supported"); for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) - *__s = (wchar_t)*__p; + *__s = *__p; __nb = __nn; } return __s; } }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> -struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> +struct _LIBCPP_TYPE_VIS __widen_from_utf8<32> : public codecvt { _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt(1) {} +_LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); + ~__widen_from_utf8(); template _LIBCPP_INLINE_VISIBILITY @@ -1435,7 +1690,7 @@ struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> if (__r == codecvt_base::error || __nn == __nb) __throw_runtime_error("locale not supported"); for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) - *__s = (wchar_t)*__p; + *__s = *__p; __nb = __nn; } return __s; @@ -1477,6 +1732,7 @@ protected: string __grouping_; }; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS numpunct : public locale::facet @@ -1507,6 +1763,7 @@ protected: char_type __thousands_sep_; string __grouping_; }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS // template class numpunct_byname @@ -1530,6 +1787,7 @@ private: void __init(const char*); }; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> class _LIBCPP_TYPE_VIS numpunct_byname : public numpunct @@ -1547,7 +1805,8 @@ protected: private: void __init(const char*); }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LOCALE +#endif // _LIBCPP___LOCALE diff --git a/include/__mbstate_t.h b/include/__mbstate_t.h new file mode 100644 index 000000000..3489f9cc0 --- /dev/null +++ b/include/__mbstate_t.h @@ -0,0 +1,44 @@ +// -*- 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___MBSTATE_T_H +#define _LIBCPP___MBSTATE_T_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +// TODO(ldionne): +// The goal of this header is to provide mbstate_t without having to pull in +// or . This is necessary because we need that type even +// when we don't have (or try to provide) support for wchar_t, because several +// types like std::fpos are defined in terms of mbstate_t. +// +// This is a gruesome hack, but I don't know how to make it cleaner for +// the time being. + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# include // for mbstate_t +#elif __has_include() +# include // works on most Unixes +#elif __has_include() +# include // works on Darwin +#else +# error "The library was configured without support for wide-characters, but we don't know how to get the definition of mbstate_t without on your platform." +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +using ::mbstate_t _LIBCPP_USING_IF_EXISTS; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MBSTATE_T_H diff --git a/include/__memory/addressof.h b/include/__memory/addressof.h new file mode 100644 index 000000000..c45dedfae --- /dev/null +++ b/include/__memory/addressof.h @@ -0,0 +1,76 @@ +// -*- 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_ADDRESSOF_H +#define _LIBCPP___MEMORY_ADDRESSOF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY +_Tp* +addressof(_Tp& __x) _NOEXCEPT +{ + return __builtin_addressof(__x); +} + +#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF) +// Objective-C++ Automatic Reference Counting uses qualified pointers +// that require special addressof() signatures. When +// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler +// itself is providing these definitions. Otherwise, we provide them. +template +inline _LIBCPP_INLINE_VISIBILITY +__strong _Tp* +addressof(__strong _Tp& __x) _NOEXCEPT +{ + return &__x; +} + +#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK +template +inline _LIBCPP_INLINE_VISIBILITY +__weak _Tp* +addressof(__weak _Tp& __x) _NOEXCEPT +{ + return &__x; +} +#endif + +template +inline _LIBCPP_INLINE_VISIBILITY +__autoreleasing _Tp* +addressof(__autoreleasing _Tp& __x) _NOEXCEPT +{ + return &__x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +__unsafe_unretained _Tp* +addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT +{ + return &__x; +} +#endif + +#if !defined(_LIBCPP_CXX03_LANG) +template _Tp* addressof(const _Tp&&) noexcept = delete; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_ADDRESSOF_H diff --git a/include/__memory/allocation_guard.h b/include/__memory/allocation_guard.h new file mode 100644 index 000000000..6412677aa --- /dev/null +++ b/include/__memory/allocation_guard.h @@ -0,0 +1,83 @@ +// -*- 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_ALLOCATION_GUARD_H +#define _LIBCPP___MEMORY_ALLOCATION_GUARD_H + +#include <__config> +#include <__memory/allocator_traits.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Helper class to allocate memory using an Allocator in an exception safe +// manner. +// +// The intended usage of this class is as follows: +// +// 0 +// 1 __allocation_guard guard(alloc, 10); +// 2 do_some_initialization_that_may_throw(guard.__get()); +// 3 save_allocated_pointer_in_a_noexcept_operation(guard.__release_ptr()); +// 4 +// +// If line (2) throws an exception during initialization of the memory, the +// guard's destructor will be called, and the memory will be released using +// Allocator deallocation. Otherwise, we release the memory from the guard on +// line (3) in an operation that can't throw -- after that, the guard is not +// responsible for the memory anymore. +// +// This is similar to a unique_ptr, except it's easier to use with a +// custom allocator. +template +struct __allocation_guard { + using _Pointer = typename allocator_traits<_Alloc>::pointer; + using _Size = typename allocator_traits<_Alloc>::size_type; + + template // we perform the allocator conversion inside the constructor + _LIBCPP_HIDE_FROM_ABI + explicit __allocation_guard(_AllocT __alloc, _Size __n) + : __alloc_(_VSTD::move(__alloc)) + , __n_(__n) + , __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important + { } + + _LIBCPP_HIDE_FROM_ABI + ~__allocation_guard() _NOEXCEPT { + if (__ptr_ != nullptr) { + allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_); + } + } + + _LIBCPP_HIDE_FROM_ABI + _Pointer __release_ptr() _NOEXCEPT { // not called __release() because it's a keyword in objective-c++ + _Pointer __tmp = __ptr_; + __ptr_ = nullptr; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + _Pointer __get() const _NOEXCEPT { + return __ptr_; + } + +private: + _Alloc __alloc_; + _Size __n_; + _Pointer __ptr_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H diff --git a/include/__memory/allocator.h b/include/__memory/allocator.h new file mode 100644 index 000000000..708bd82b0 --- /dev/null +++ b/include/__memory/allocator.h @@ -0,0 +1,249 @@ +// -*- 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_ALLOCATOR_H +#define _LIBCPP___MEMORY_ALLOCATOR_H + +#include <__config> +#include <__memory/allocator_traits.h> +#include <__utility/forward.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class allocator; + +#if _LIBCPP_STD_VER <= 17 +template <> +class _LIBCPP_TEMPLATE_VIS allocator +{ +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 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; +}; + +template <> +class _LIBCPP_TEMPLATE_VIS allocator +{ +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 struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; +}; +#endif + +// This class provides a non-trivial default constructor to the class that derives from it +// if the condition is satisfied. +// +// The second template parameter exists to allow giving a unique type to __non_trivial_if, +// which makes it possible to avoid breaking the ABI when making this a base class of an +// existing class. Without that, imagine we have classes D1 and D2, both of which used to +// have no base classes, but which now derive from __non_trivial_if. The layout of a class +// that inherits from both D1 and D2 will change because the two __non_trivial_if base +// classes are not allowed to share the same address. +// +// By making those __non_trivial_if base classes unique, we work around this problem and +// it is safe to start deriving from __non_trivial_if in existing classes. +template +struct __non_trivial_if { }; + +template +struct __non_trivial_if { + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __non_trivial_if() _NOEXCEPT { } +}; + +// allocator +// +// Note: For ABI compatibility between C++20 and previous standards, we make +// allocator trivial in C++20. + +template +class _LIBCPP_TEMPLATE_VIS allocator + : private __non_trivial_if::value, allocator<_Tp> > +{ + static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types"); +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp value_type; + typedef true_type propagate_on_container_move_assignment; + typedef true_type is_always_equal; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator() _NOEXCEPT = default; + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator(const allocator<_Up>&) _NOEXCEPT { } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _Tp* allocate(size_t __n) { + if (__n > allocator_traits::max_size(*this)) + __throw_bad_array_new_length(); + if (__libcpp_is_constant_evaluated()) { + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } else { + return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); + } + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void deallocate(_Tp* __p, size_t __n) _NOEXCEPT { + if (__libcpp_is_constant_evaluated()) { + ::operator delete(__p); + } else { + _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); + } + } + + // C++20 Removed members +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) + _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer; + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer; + _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference; + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference; + + template + struct _LIBCPP_DEPRECATED_IN_CXX17 rebind { + typedef allocator<_Up> other; + }; + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + pointer address(reference __x) const _NOEXCEPT { + return _VSTD::addressof(__x); + } + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + const_pointer address(const_reference __x) const _NOEXCEPT { + return _VSTD::addressof(__x); + } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 + _Tp* allocate(size_t __n, const void*) { + return allocate(__n); + } + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { + return size_type(~0) / sizeof(_Tp); + } + + template + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + void construct(_Up* __p, _Args&&... __args) { + ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); + } + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + void destroy(pointer __p) { + __p->~_Tp(); + } +#endif +}; + +template +class _LIBCPP_TEMPLATE_VIS allocator + : private __non_trivial_if::value, allocator > +{ + static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types"); +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef const _Tp value_type; + typedef true_type propagate_on_container_move_assignment; + typedef true_type is_always_equal; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator() _NOEXCEPT = default; + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator(const allocator<_Up>&) _NOEXCEPT { } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + const _Tp* allocate(size_t __n) { + if (__n > allocator_traits::max_size(*this)) + __throw_bad_array_new_length(); + if (__libcpp_is_constant_evaluated()) { + return static_cast(::operator new(__n * sizeof(_Tp))); + } else { + return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); + } + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void deallocate(const _Tp* __p, size_t __n) { + if (__libcpp_is_constant_evaluated()) { + ::operator delete(const_cast<_Tp*>(__p)); + } else { + _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); + } + } + + // C++20 Removed members +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer; + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer; + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference; + _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference; + + template + struct _LIBCPP_DEPRECATED_IN_CXX17 rebind { + typedef allocator<_Up> other; + }; + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + const_pointer address(const_reference __x) const _NOEXCEPT { + return _VSTD::addressof(__x); + } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 + const _Tp* allocate(size_t __n, const void*) { + return allocate(__n); + } + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { + return size_type(~0) / sizeof(_Tp); + } + + template + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + void construct(_Up* __p, _Args&&... __args) { + ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); + } + + _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY + void destroy(pointer __p) { + __p->~_Tp(); + } +#endif +}; + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_ALLOCATOR_H diff --git a/include/__memory/allocator_arg_t.h b/include/__memory/allocator_arg_t.h new file mode 100644 index 000000000..f5a116dbb --- /dev/null +++ b/include/__memory/allocator_arg_t.h @@ -0,0 +1,78 @@ +// -*- 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_ALLOCATOR_ARG_T_H +#define _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H + +#include <__config> +#include <__memory/uses_allocator.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; + +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) +extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; +#else +/* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); +#endif + +#ifndef _LIBCPP_CXX03_LANG + +// allocator construction + +template +struct __uses_alloc_ctor_imp +{ + typedef _LIBCPP_NODEBUG typename __uncvref<_Alloc>::type _RawAlloc; + static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; + static const bool __ic = + is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; + static const int value = __ua ? 2 - __ic : 0; +}; + +template +struct __uses_alloc_ctor + : integral_constant::value> + {}; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); +} + +// FIXME: This should have a version which takes a non-const alloc. +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); +} + +// FIXME: This should have a version which takes a non-const alloc. +template +inline _LIBCPP_INLINE_VISIBILITY +void __user_alloc_construct_impl (integral_constant, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) +{ + new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H diff --git a/include/__memory/allocator_traits.h b/include/__memory/allocator_traits.h new file mode 100644 index 000000000..f4c8fa02d --- /dev/null +++ b/include/__memory/allocator_traits.h @@ -0,0 +1,405 @@ +// -*- 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_ALLOCATOR_TRAITS_H +#define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H + +#include <__config> +#include <__memory/construct_at.h> +#include <__memory/pointer_traits.h> +#include <__utility/forward.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#define _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(NAME, PROPERTY) \ + template struct NAME : false_type { }; \ + template struct NAME<_Tp, typename __void_t::type> : true_type { } + +// __pointer +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_pointer, pointer); +template ::type, + bool = __has_pointer<_RawAlloc>::value> +struct __pointer { + using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer; +}; +template +struct __pointer<_Tp, _Alloc, _RawAlloc, false> { + using type _LIBCPP_NODEBUG = _Tp*; +}; + +// __const_pointer +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_pointer, const_pointer); +template ::value> +struct __const_pointer { + using type _LIBCPP_NODEBUG = typename _Alloc::const_pointer; +}; +template +struct __const_pointer<_Tp, _Ptr, _Alloc, false> { +#ifdef _LIBCPP_CXX03_LANG + using type = typename pointer_traits<_Ptr>::template rebind::other; +#else + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; +#endif +}; + +// __void_pointer +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_void_pointer, void_pointer); +template ::value> +struct __void_pointer { + using type _LIBCPP_NODEBUG = typename _Alloc::void_pointer; +}; +template +struct __void_pointer<_Ptr, _Alloc, false> { +#ifdef _LIBCPP_CXX03_LANG + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind::other; +#else + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; +#endif +}; + +// __const_void_pointer +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_const_void_pointer, const_void_pointer); +template ::value> +struct __const_void_pointer { + using type _LIBCPP_NODEBUG = typename _Alloc::const_void_pointer; +}; +template +struct __const_void_pointer<_Ptr, _Alloc, false> { +#ifdef _LIBCPP_CXX03_LANG + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind::other; +#else + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::template rebind; +#endif +}; + +// __size_type +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_size_type, size_type); +template ::value> +struct __size_type : make_unsigned<_DiffType> { }; +template +struct __size_type<_Alloc, _DiffType, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::size_type; +}; + +// __alloc_traits_difference_type +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_alloc_traits_difference_type, difference_type); +template ::value> +struct __alloc_traits_difference_type { + using type _LIBCPP_NODEBUG = typename pointer_traits<_Ptr>::difference_type; +}; +template +struct __alloc_traits_difference_type<_Alloc, _Ptr, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::difference_type; +}; + +// __propagate_on_container_copy_assignment +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_copy_assignment, propagate_on_container_copy_assignment); +template ::value> +struct __propagate_on_container_copy_assignment : false_type { }; +template +struct __propagate_on_container_copy_assignment<_Alloc, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_copy_assignment; +}; + +// __propagate_on_container_move_assignment +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_move_assignment, propagate_on_container_move_assignment); +template ::value> +struct __propagate_on_container_move_assignment : false_type { }; +template +struct __propagate_on_container_move_assignment<_Alloc, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_move_assignment; +}; + +// __propagate_on_container_swap +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_propagate_on_container_swap, propagate_on_container_swap); +template ::value> +struct __propagate_on_container_swap : false_type { }; +template +struct __propagate_on_container_swap<_Alloc, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::propagate_on_container_swap; +}; + +// __is_always_equal +_LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_is_always_equal, is_always_equal); +template ::value> +struct __is_always_equal : is_empty<_Alloc> { }; +template +struct __is_always_equal<_Alloc, true> { + using type _LIBCPP_NODEBUG = typename _Alloc::is_always_equal; +}; + +// __allocator_traits_rebind +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template +struct __has_rebind_other : false_type { }; +template +struct __has_rebind_other<_Tp, _Up, typename __void_t< + typename _Tp::template rebind<_Up>::other +>::type> : true_type { }; + +template ::value> +struct __allocator_traits_rebind { + using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>::other; +}; +template