aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt132
-rw-r--r--LICENSE.TXT2
-rw-r--r--appveyor-reqs-install.cmd2
-rw-r--r--appveyor.yml8
-rw-r--r--benchmarks/CMakeLists.txt81
-rw-r--r--benchmarks/CartesianBenchmarks.hpp135
-rw-r--r--benchmarks/algorithms.bench.cpp298
-rw-r--r--benchmarks/algorithms.partition_point.bench.cpp124
-rw-r--r--benchmarks/function.bench.cpp232
-rw-r--r--benchmarks/lit.cfg.py23
-rw-r--r--benchmarks/lit.site.cfg.py.in10
-rw-r--r--benchmarks/ordered_set.bench.cpp249
-rw-r--r--benchmarks/string.bench.cpp347
-rw-r--r--benchmarks/stringstream.bench.cpp4
-rw-r--r--benchmarks/unordered_set_operations.bench.cpp19
-rw-r--r--cmake/Modules/HandleCompilerRT.cmake3
-rw-r--r--cmake/Modules/HandleLibCXXABI.cmake2
-rw-r--r--cmake/Modules/HandleLibcxxFlags.cmake24
-rw-r--r--docs/BuildingLibcxx.rst41
-rw-r--r--docs/DesignDocs/AvailabilityMarkup.rst49
-rw-r--r--docs/DesignDocs/CapturingConfigInfo.rst2
-rw-r--r--docs/DesignDocs/FeatureTestMacros.rst44
-rw-r--r--docs/DesignDocs/VisibilityMacros.rst71
-rw-r--r--docs/FeatureTestMacroTable.rst200
-rw-r--r--docs/ReleaseNotes.rst62
-rw-r--r--docs/TestingLibcxx.rst11
-rw-r--r--docs/UsingLibcxx.rst81
-rw-r--r--docs/conf.py8
-rw-r--r--docs/index.rst29
-rw-r--r--fuzzing/fuzzing.cpp829
-rw-r--r--include/CMakeLists.txt2
-rw-r--r--include/__bit_reference13
-rw-r--r--include/__config343
-rw-r--r--include/__config_site.in2
-rw-r--r--include/__debug2
-rw-r--r--include/__functional_base8
-rw-r--r--include/__hash_table315
-rw-r--r--include/__libcpp_version2
-rw-r--r--include/__locale16
-rw-r--r--include/__mutex_base6
-rw-r--r--include/__node_handle2
-rw-r--r--include/__sso_allocator6
-rw-r--r--include/__string97
-rw-r--r--include/__threading_support2
-rw-r--r--include/__tree106
-rw-r--r--include/__tuple18
-rw-r--r--include/algorithm201
-rw-r--r--include/any9
-rw-r--r--include/array17
-rw-r--r--include/atomic5
-rw-r--r--include/bit158
-rw-r--r--include/bitset14
-rw-r--r--include/charconv13
-rw-r--r--include/chrono1283
-rw-r--r--include/cmath1
-rw-r--r--include/complex1
-rw-r--r--include/cstddef29
-rw-r--r--include/cstdlib4
-rw-r--r--include/ctime2
-rw-r--r--include/deque28
-rw-r--r--include/exception5
-rw-r--r--include/experimental/any18
-rw-r--r--include/experimental/chrono18
-rw-r--r--include/experimental/coroutine6
-rw-r--r--include/experimental/dynarray305
-rw-r--r--include/experimental/memory_resource8
-rw-r--r--include/experimental/numeric12
-rw-r--r--include/experimental/optional12
-rw-r--r--include/experimental/ratio18
-rw-r--r--include/experimental/string_view16
-rw-r--r--include/experimental/system_error12
-rw-r--r--include/experimental/tuple12
-rw-r--r--include/filesystem99
-rw-r--r--include/forward_list18
-rw-r--r--include/fstream1
-rw-r--r--include/functional948
-rw-r--r--include/future19
-rw-r--r--include/iomanip1
-rw-r--r--include/iosfwd17
-rw-r--r--include/istream82
-rw-r--r--include/iterator20
-rw-r--r--include/limits2
-rw-r--r--include/list22
-rw-r--r--include/locale28
-rw-r--r--include/map122
-rw-r--r--include/memory139
-rw-r--r--include/module.modulemap8
-rw-r--r--include/mutex3
-rw-r--r--include/new169
-rw-r--r--include/numeric9
-rw-r--r--include/optional12
-rw-r--r--include/ostream19
-rw-r--r--include/random4
-rw-r--r--include/regex24
-rw-r--r--include/scoped_allocator1
-rw-r--r--include/set126
-rw-r--r--include/shared_mutex16
-rw-r--r--include/span96
-rw-r--r--include/sstream8
-rw-r--r--include/stddef.h2
-rw-r--r--include/stdexcept12
-rw-r--r--include/streambuf40
-rw-r--r--include/string200
-rw-r--r--include/string_view25
-rw-r--r--include/support/win32/locale_win32.h4
-rw-r--r--include/thread2
-rw-r--r--include/tuple29
-rw-r--r--include/type_traits29
-rw-r--r--include/typeinfo10
-rw-r--r--include/unordered_map126
-rw-r--r--include/unordered_set121
-rw-r--r--include/utility75
-rw-r--r--include/valarray111
-rw-r--r--include/variant48
-rw-r--r--include/vector39
-rw-r--r--include/version211
-rw-r--r--lib/CMakeLists.txt139
-rw-r--r--lib/abi/CHANGELOG.TXT112
-rw-r--r--lib/abi/CMakeLists.txt15
-rw-r--r--lib/abi/x86_64-apple-darwin.v1.abilist22
-rw-r--r--lib/abi/x86_64-apple-darwin.v2.abilist103
-rw-r--r--lib/abi/x86_64-unknown-linux-gnu.v1.abilist24
-rw-r--r--lib/libc++abi2.exp10
-rw-r--r--src/experimental/memory_resource.cpp5
-rw-r--r--src/filesystem/filesystem_common.h31
-rw-r--r--src/filesystem/operations.cpp110
-rw-r--r--src/future.cpp5
-rw-r--r--src/iostream.cpp20
-rw-r--r--src/new.cpp14
-rw-r--r--src/support/runtime/exception_fallback.ipp16
-rw-r--r--src/support/runtime/exception_glibcxx.ipp5
-rw-r--r--src/support/runtime/exception_libcxxrt.ipp15
-rw-r--r--src/support/runtime/exception_msvc.ipp14
-rw-r--r--src/thread.cpp4
-rw-r--r--test/CMakeLists.txt13
-rw-r--r--test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp4
-rw-r--r--test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.fail.cpp50
-rw-r--r--test/libcxx/algorithms/debug_less.pass.cpp51
-rw-r--r--test/libcxx/algorithms/half_positive.pass.cpp56
-rw-r--r--test/libcxx/containers/associative/non_const_comparator.fail.cpp3
-rw-r--r--test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp (renamed from test/libcxx/type_traits/is_floating_point.pass.cpp)26
-rw-r--r--test/libcxx/containers/sequences/vector/db_back.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_cback.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_cfront.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_cindex.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_front.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_index.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp3
-rw-r--r--test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp26
-rw-r--r--test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp54
-rw-r--r--test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp57
-rw-r--r--test/libcxx/containers/unord/non_const_comparator.fail.cpp8
-rw-r--r--test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp3
-rw-r--r--test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp3
-rw-r--r--test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp3
-rw-r--r--test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp3
-rw-r--r--test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp39
-rw-r--r--test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.fail.cpp59
-rw-r--r--test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp22
-rw-r--r--test/libcxx/diagnostics/enable_nodiscard.fail.cpp33
-rw-r--r--test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.fail.cpp33
-rw-r--r--test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.fail.cpp31
-rw-r--r--test/libcxx/diagnostics/nodiscard.pass.cpp15
-rw-r--r--test/libcxx/diagnostics/nodiscard_aftercxx17.fail.cpp (renamed from test/libcxx/diagnostics/nodiscard.fail.cpp)1
-rw-r--r--test/libcxx/diagnostics/nodiscard_aftercxx17.pass.cpp (renamed from test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp)21
-rw-r--r--test/libcxx/diagnostics/nodiscard_extensions.fail.cpp35
-rw-r--r--test/libcxx/diagnostics/nodiscard_extensions.pass.cpp29
-rw-r--r--test/libcxx/double_include.sh.cpp2
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp83
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp102
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp35
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp69
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp47
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp94
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp110
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp56
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp74
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp76
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp48
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/lit.local.cfg3
-rw-r--r--test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/diagnostics/syserr/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp7
-rw-r--r--test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp2
-rw-r--r--test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/strings/string.view/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/utilities/any/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/utilities/optional/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/utilities/ratio/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/utilities/time/version.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp18
-rw-r--r--test/libcxx/experimental/utilities/tuple/version.pass.cpp21
-rw-r--r--test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp35
-rw-r--r--test/libcxx/language.support/cxa_deleted_virtual.pass.cpp1
-rw-r--r--test/libcxx/language.support/has_c11_features.pass.cpp3
-rw-r--r--test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp260
-rw-r--r--test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp8
-rw-r--r--test/libcxx/libcpp_alignof.pass.cpp37
-rw-r--r--test/libcxx/memory/aligned_allocation_macro.pass.cpp (renamed from test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp)32
-rw-r--r--test/libcxx/min_max_macros.sh.cpp4
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp3
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp63
-rw-r--r--test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp10
-rw-r--r--test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp1
-rw-r--r--test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp (renamed from test/std/utilities/optional/optional.object/special_member_gen.pass.cpp)32
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp54
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp62
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp64
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp36
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp15
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp2
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp38
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp63
-rw-r--r--test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp15
-rw-r--r--test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp2
-rw-r--r--test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp3
-rw-r--r--test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp2
-rw-r--r--test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp1
-rw-r--r--test/std/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp20
-rw-r--r--test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp37
-rw-r--r--test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp4
-rw-r--r--test/std/containers/Emplaceable.h2
-rw-r--r--test/std/containers/associative/map/map.access/at.pass.cpp3
-rw-r--r--test/std/containers/associative/map/map.access/index_key.pass.cpp1
-rw-r--r--test/std/containers/associative/map/map.access/index_rv_key.pass.cpp1
-rw-r--r--test/std/containers/associative/map/map.access/max_size.pass.cpp22
-rw-r--r--test/std/containers/associative/map/map.erasure/erase_if.pass.cpp79
-rw-r--r--test/std/containers/associative/map/map.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/associative/map/map.modifiers/merge.pass.cpp150
-rw-r--r--test/std/containers/associative/multimap/max_size.pass.cpp22
-rw-r--r--test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp89
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp150
-rw-r--r--test/std/containers/associative/multiset/clear.pass.cpp5
-rw-r--r--test/std/containers/associative/multiset/insert_emplace_allocator_requirements.pass.cpp (renamed from test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp)1
-rw-r--r--test/std/containers/associative/multiset/max_size.pass.cpp8
-rw-r--r--test/std/containers/associative/multiset/merge.pass.cpp149
-rw-r--r--test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/associative/set/clear.pass.cpp5
-rw-r--r--test/std/containers/associative/set/max_size.pass.cpp8
-rw-r--r--test/std/containers/associative/set/merge.pass.cpp149
-rw-r--r--test/std/containers/associative/set/set.erasure/erase_if.pass.cpp67
-rw-r--r--test/std/containers/container.adaptors/queue/queue.defn/emplace.pass.cpp2
-rw-r--r--test/std/containers/container.adaptors/stack/stack.defn/emplace.pass.cpp2
-rw-r--r--test/std/containers/container.node/node_handle.pass.cpp4
-rw-r--r--test/std/containers/map_allocator_requirement_test_templates.h8
-rw-r--r--test/std/containers/sequences/array/array.data/data.pass.cpp18
-rw-r--r--test/std/containers/sequences/array/array.data/data_const.pass.cpp12
-rw-r--r--test/std/containers/sequences/array/array.tuple/get.fail.cpp2
-rw-r--r--test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp2
-rw-r--r--test/std/containers/sequences/array/begin.pass.cpp16
-rw-r--r--test/std/containers/sequences/array/compare.pass.cpp33
-rw-r--r--test/std/containers/sequences/array/size_and_alignment.pass.cpp2
-rw-r--r--test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp8
-rw-r--r--test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp78
-rw-r--r--test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/sequences/deque/deque.modifiers/clear.pass.cpp67
-rw-r--r--test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp32
-rw-r--r--test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp32
-rw-r--r--test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp78
-rw-r--r--test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp7
-rw-r--r--test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp1
-rw-r--r--test/std/containers/sequences/forwardlist/max_size.pass.cpp8
-rw-r--r--test/std/containers/sequences/list/list.capacity/max_size.pass.cpp8
-rw-r--r--test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp4
-rw-r--r--test/std/containers/sequences/list/list.erasure/erase.pass.cpp78
-rw-r--r--test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/sequences/list/list.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/sequences/list/list.ops/merge.pass.cpp11
-rw-r--r--test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp10
-rw-r--r--test/std/containers/sequences/vector.bool/construct_default.pass.cpp17
-rw-r--r--test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp6
-rw-r--r--test/std/containers/sequences/vector.bool/move.pass.cpp12
-rw-r--r--test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp8
-rw-r--r--test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp33
-rw-r--r--test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp2
-rw-r--r--test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp4
-rw-r--r--test/std/containers/sequences/vector/vector.cons/move.pass.cpp1
-rw-r--r--test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp78
-rw-r--r--test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp56
-rw-r--r--test/std/containers/set_allocator_requirement_test_templates.h49
-rw-r--r--test/std/containers/unord/unord.map/compare.pass.cpp3
-rw-r--r--test/std/containers/unord/unord.map/erase_if.pass.cpp80
-rw-r--r--test/std/containers/unord/unord.map/max_size.pass.cpp8
-rw-r--r--test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp2
-rw-r--r--test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp5
-rw-r--r--test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp157
-rw-r--r--test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp39
-rw-r--r--test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp39
-rw-r--r--test/std/containers/unord/unord.multimap/erase_if.pass.cpp90
-rw-r--r--test/std/containers/unord/unord.multimap/local_iterators.pass.cpp273
-rw-r--r--test/std/containers/unord/unord.multimap/max_size.pass.cpp8
-rw-r--r--test/std/containers/unord/unord.multimap/rehash.pass.cpp36
-rw-r--r--test/std/containers/unord/unord.multimap/reserve.pass.cpp23
-rw-r--r--test/std/containers/unord/unord.multimap/swap_member.pass.cpp121
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp2
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp5
-rw-r--r--test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp157
-rw-r--r--test/std/containers/unord/unord.multiset/clear.pass.cpp5
-rw-r--r--test/std/containers/unord/unord.multiset/erase_if.pass.cpp91
-rw-r--r--test/std/containers/unord/unord.multiset/erase_range.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multiset/insert_emplace_allocator_requirements.pass.cpp (renamed from test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp)1
-rw-r--r--test/std/containers/unord/unord.multiset/max_size.pass.cpp8
-rw-r--r--test/std/containers/unord/unord.multiset/merge.pass.cpp154
-rw-r--r--test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp2
-rw-r--r--test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.set/clear.pass.cpp5
-rw-r--r--test/std/containers/unord/unord.set/erase_if.pass.cpp81
-rw-r--r--test/std/containers/unord/unord.set/erase_range.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.set/max_size.pass.cpp8
-rw-r--r--test/std/containers/unord/unord.set/merge.pass.cpp154
-rw-r--r--test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp2
-rw-r--r--test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp1
-rw-r--r--test/std/containers/views/span.comparison/op.eq.pass.cpp168
-rw-r--r--test/std/containers/views/span.comparison/op.ge.pass.cpp153
-rw-r--r--test/std/containers/views/span.comparison/op.gt.pass.cpp154
-rw-r--r--test/std/containers/views/span.comparison/op.le.pass.cpp153
-rw-r--r--test/std/containers/views/span.comparison/op.lt.pass.cpp154
-rw-r--r--test/std/containers/views/span.comparison/op.ne.pass.cpp168
-rw-r--r--test/std/containers/views/span.cons/array.fail.cpp8
-rw-r--r--test/std/containers/views/span.cons/array.pass.cpp2
-rw-r--r--test/std/containers/views/span.cons/assign.pass.cpp14
-rw-r--r--test/std/containers/views/span.cons/container.fail.cpp4
-rw-r--r--test/std/containers/views/span.cons/container.pass.cpp2
-rw-r--r--test/std/containers/views/span.cons/copy.pass.cpp4
-rw-r--r--test/std/containers/views/span.cons/deduct.pass.cpp12
-rw-r--r--test/std/containers/views/span.cons/default.fail.cpp6
-rw-r--r--test/std/containers/views/span.cons/default.pass.cpp2
-rw-r--r--test/std/containers/views/span.cons/ptr_len.fail.cpp6
-rw-r--r--test/std/containers/views/span.cons/ptr_len.pass.cpp4
-rw-r--r--test/std/containers/views/span.cons/ptr_ptr.fail.cpp6
-rw-r--r--test/std/containers/views/span.cons/ptr_ptr.pass.cpp4
-rw-r--r--test/std/containers/views/span.cons/span.fail.cpp4
-rw-r--r--test/std/containers/views/span.cons/span.pass.cpp2
-rw-r--r--test/std/containers/views/span.cons/stdarray.pass.cpp4
-rw-r--r--test/std/containers/views/span.elem/data.pass.cpp2
-rw-r--r--test/std/containers/views/span.elem/op_idx.pass.cpp6
-rw-r--r--test/std/containers/views/span.iterators/begin.pass.cpp2
-rw-r--r--test/std/containers/views/span.iterators/end.pass.cpp8
-rw-r--r--test/std/containers/views/span.iterators/rbegin.pass.cpp2
-rw-r--r--test/std/containers/views/span.iterators/rend.pass.cpp2
-rw-r--r--test/std/containers/views/span.objectrep/as_bytes.pass.cpp4
-rw-r--r--test/std/containers/views/span.objectrep/as_writeable_bytes.fail.cpp2
-rw-r--r--test/std/containers/views/span.objectrep/as_writeable_bytes.pass.cpp4
-rw-r--r--test/std/containers/views/span.obs/empty.pass.cpp4
-rw-r--r--test/std/containers/views/span.obs/size.pass.cpp2
-rw-r--r--test/std/containers/views/span.obs/size_bytes.pass.cpp2
-rw-r--r--test/std/containers/views/span.sub/first.pass.cpp6
-rw-r--r--test/std/containers/views/span.sub/last.pass.cpp6
-rw-r--r--test/std/containers/views/span.sub/subspan.pass.cpp2
-rw-r--r--test/std/containers/views/types.pass.cpp8
-rw-r--r--test/std/depr/depr.c.headers/float_h.pass.cpp8
-rw-r--r--test/std/depr/depr.c.headers/math_h.pass.cpp39
-rw-r--r--test/std/depr/depr.c.headers/stdlib_h.pass.cpp4
-rw-r--r--test/std/depr/depr.c.headers/uchar_h.pass.cpp1
-rw-r--r--test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.fail.cpp31
-rw-r--r--test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.fail.cpp31
-rw-r--r--test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.fail.cpp31
-rw-r--r--test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.fail.cpp31
-rw-r--r--test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp8
-rw-r--r--test/std/experimental/simd/simd.access/default.pass.cpp2
-rw-r--r--test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp1
-rw-r--r--test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp1
-rw-r--r--test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp55
-rw-r--r--test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp4
-rw-r--r--test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp27
-rw-r--r--test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp4
-rw-r--r--test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp33
-rw-r--r--test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp1
-rw-r--r--test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp1
-rw-r--r--test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp21
-rw-r--r--test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp2
-rw-r--r--test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp6
-rw-r--r--test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp126
-rw-r--r--test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp22
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp22
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp33
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp5
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp5
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp5
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp5
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp3
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp3
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp3
-rw-r--r--test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp3
-rw-r--r--test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp8
-rw-r--r--test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/std.manip/setbase.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/std.manip/setfill.pass.cpp1
-rw-r--r--test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp2
-rw-r--r--test/std/input.output/iostream.format/std.manip/setw.pass.cpp2
-rw-r--r--test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp6
-rw-r--r--test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp122
-rw-r--r--test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp1
-rw-r--r--test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp2
-rw-r--r--test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp2
-rw-r--r--test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp2
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp31
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp26
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp25
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp25
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.sh.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.fail.cpp)7
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.sh.cpp26
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.sh.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.fail.cpp)7
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.sh.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.fail.cpp)7
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp12
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp31
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp25
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp25
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp25
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.sh.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.fail.cpp)9
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.sh.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.fail.cpp)7
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp12
-rw-r--r--test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp2
-rw-r--r--test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp10
-rw-r--r--test/std/language.support/support.limits/c.limits/cfloat.pass.cpp8
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp10
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/digits.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/digits10.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/epsilon.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm_loss.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/has_infinity.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/has_quiet_NaN.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/has_signaling_NaN.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_bounded.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_exact.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_iec559.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_integer.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_modulo.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/is_signed.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/lowest.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/max.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/max_digits10.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent10.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/min.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent10.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/quiet_NaN.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/radix.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/round_error.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/round_style.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/signaling_NaN.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp5
-rw-r--r--test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp192
-rw-r--r--test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp105
-rw-r--r--test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp122
-rw-r--r--test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp32
-rw-r--r--test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp82
-rw-r--r--test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp91
-rw-r--r--test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp34
-rw-r--r--test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp99
-rw-r--r--test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp34
-rw-r--r--test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp82
-rw-r--r--test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp148
-rw-r--r--test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp245
-rwxr-xr-xtest/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py977
-rw-r--r--test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp183
-rw-r--r--test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp148
-rw-r--r--test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp171
-rw-r--r--test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp247
-rw-r--r--test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp34
-rw-r--r--test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp105
-rw-r--r--test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp91
-rw-r--r--test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp59
-rw-r--r--test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp148
-rw-r--r--test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp114
-rw-r--r--test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp174
-rw-r--r--test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp108
-rw-r--r--test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp157
-rw-r--r--test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp397
-rw-r--r--test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp171
-rw-r--r--test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp148
-rw-r--r--test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp195
-rw-r--r--test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp56
-rw-r--r--test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp122
-rw-r--r--test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp2178
-rw-r--r--test/std/language.support/support.runtime/cstdlib.pass.cpp6
-rw-r--r--test/std/language.support/support.runtime/ctime.pass.cpp2
-rw-r--r--test/std/language.support/support.start.term/quick_exit.pass.cpp2
-rw-r--r--test/std/language.support/support.start.term/quick_exit_check1.fail.cpp1
-rw-r--r--test/std/language.support/support.start.term/quick_exit_check2.fail.cpp2
-rw-r--r--test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp1
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp10
-rw-r--r--test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp2
-rw-r--r--test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp3
-rw-r--r--test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp3
-rw-r--r--test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp3
-rw-r--r--test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp4
-rw-r--r--test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp4
-rw-r--r--test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp4
-rw-r--r--test/std/numerics/c.math/cmath.pass.cpp3
-rw-r--r--test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp2
-rw-r--r--test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq_all_zero.pass.cpp81
-rw-r--r--test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp28
-rw-r--r--test/std/re/re.alg/re.alg.match/basic.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.match/ecma.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.match/extended.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.match/inverted_character_classes.pass.cpp44
-rw-r--r--test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.search/awk.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.search/basic.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.search/ecma.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.search/extended.pass.cpp3
-rw-r--r--test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp2
-rw-r--r--test/std/re/re.grammar/excessive_brace_count.pass.cpp2
-rw-r--r--test/std/re/re.results/re.results.const/copy.pass.cpp41
-rw-r--r--test/std/re/re.results/re.results.const/copy_assign.pass.cpp50
-rw-r--r--test/std/re/re.results/re.results.const/move.pass.cpp48
-rw-r--r--test/std/re/re.results/re.results.const/move_assign.pass.cpp51
-rw-r--r--test/std/re/re.traits/lookup_collatename.pass.cpp3
-rw-r--r--test/std/re/re.traits/transform.pass.cpp3
-rw-r--r--test/std/re/re.traits/transform_primary.pass.cpp3
-rw-r--r--test/std/re/re.traits/translate_nocase.pass.cpp8
-rw-r--r--test/std/strings/basic.string.hash/enabled_hashes.pass.cpp3
-rw-r--r--test/std/strings/basic.string.hash/strings.pass.cpp3
-rw-r--r--test/std/strings/basic.string.literals/literal.pass.cpp46
-rw-r--r--test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp1
-rw-r--r--test/std/strings/basic.string/string.capacity/reserve.pass.cpp9
-rw-r--r--test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp12
-rw-r--r--test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp2
-rw-r--r--test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp14
-rw-r--r--test/std/strings/basic.string/string.iterators/iterators.pass.cpp14
-rw-r--r--test/std/strings/c.strings/cctype.pass.cpp51
-rw-r--r--test/std/strings/c.strings/cstring.pass.cpp57
-rw-r--r--test/std/strings/c.strings/cuchar.pass.cpp2
-rw-r--r--test/std/strings/c.strings/cwchar.pass.cpp131
-rw-r--r--test/std/strings/c.strings/cwctype.pass.cpp43
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp39
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp30
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp58
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp32
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp26
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp28
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp31
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp46
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp41
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp28
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp36
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp31
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp29
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp29
-rw-r--r--test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp34
-rw-r--r--test/std/strings/string.classes/typedefs.pass.cpp10
-rw-r--r--test/std/strings/string.conversions/stod.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stof.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stoi.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stol.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stoll.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stoul.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/stoull.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/to_string.pass.cpp1
-rw-r--r--test/std/strings/string.conversions/to_wstring.pass.cpp1
-rw-r--r--test/std/strings/string.view/string.view.capacity/capacity.pass.cpp23
-rw-r--r--test/std/strings/string.view/string.view.cons/assign.pass.cpp22
-rw-r--r--test/std/strings/string.view/string.view.cons/default.pass.cpp16
-rw-r--r--test/std/strings/string.view/string.view.cons/from_string.pass.cpp6
-rw-r--r--test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp3
-rw-r--r--test/std/strings/string.view/string.view.hash/string_view.pass.cpp3
-rw-r--r--test/std/strings/string.view/string.view.iterators/begin.pass.cpp15
-rw-r--r--test/std/strings/string.view/string.view.iterators/end.pass.cpp15
-rw-r--r--test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp15
-rw-r--r--test/std/strings/string.view/string.view.iterators/rend.pass.cpp15
-rw-r--r--test/std/strings/string.view/string.view.ops/compare.pointer_size.pass.cpp1
-rw-r--r--test/std/strings/string.view/string.view.ops/compare.size_size_sv.pass.cpp1
-rw-r--r--test/std/strings/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp1
-rw-r--r--test/std/strings/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp1
-rw-r--r--test/std/strings/string.view/string.view.ops/copy.pass.cpp1
-rw-r--r--test/std/strings/string.view/string_view.literals/literal.pass.cpp46
-rw-r--r--test/std/strings/string.view/types.pass.cpp3
-rw-r--r--test/std/strings/strings.erasure/erase.pass.cpp76
-rw-r--r--test/std/strings/strings.erasure/erase_if.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.async/async_race.38682.pass.cpp69
-rw-r--r--test/std/thread/futures/futures.shared_future/wait_until.pass.cpp2
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp2
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp2
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp2
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp2
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp2
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp2
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp2
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp14
-rw-r--r--test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp1
-rw-r--r--test/std/utilities/any/any.class/any.assign/copy.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.assign/move.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.assign/value.pass.cpp15
-rw-r--r--test/std/utilities/any/any.class/any.cons/copy.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.cons/move.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.cons/value.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp13
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp13
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp13
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp13
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp4
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp4
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp4
-rw-r--r--test/std/utilities/any/any.nonmembers/make_any.pass.cpp13
-rw-r--r--test/std/utilities/any/any.nonmembers/swap.pass.cpp13
-rw-r--r--test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp13
-rw-r--r--test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp13
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp3
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp14
-rw-r--r--test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.fail.cpp35
-rw-r--r--test/std/utilities/function.objects/negators/not1.depr_in_cxx17.fail.cpp33
-rw-r--r--test/std/utilities/function.objects/negators/not2.depr_in_cxx17.fail.cpp34
-rw-r--r--test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.fail.cpp34
-rw-r--r--test/std/utilities/function.objects/refwrap/type_properties.pass.cpp9
-rw-r--r--test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp58
-rw-r--r--test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp51
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp2
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp1
-rw-r--r--test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp1
-rw-r--r--test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp1
-rw-r--r--test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp18
-rw-r--r--test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp8
-rw-r--r--test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp7
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp8
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp9
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp9
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/type_identity.pass.cpp40
-rw-r--r--test/std/utilities/meta/meta.type.synop/endian.pass.cpp1
-rw-r--r--test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp8
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp3
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp11
-rw-r--r--test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp8
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp6
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp38
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp36
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp6
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/special_members.pass.cpp63
-rw-r--r--test/std/utilities/optional/optional.object/triviality.pass.cpp97
-rw-r--r--test/std/utilities/optional/optional.specalg/make_optional.pass.cpp8
-rw-r--r--test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp1
-rw-r--r--test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp1
-rw-r--r--test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp1
-rw-r--r--test/std/utilities/template.bitset/bitset.members/test.pass.cpp1
-rw-r--r--test/std/utilities/template.bitset/includes.pass.cpp11
-rw-r--r--test/std/utilities/time/date.time/ctime.pass.cpp6
-rw-r--r--test/std/utilities/time/days.pass.cpp28
-rw-r--r--test/std/utilities/time/months.pass.cpp29
-rw-r--r--test/std/utilities/time/time.cal/euclidian.h39
-rw-r--r--test/std/utilities/time/time.cal/nothing_to_do.pass.cpp (renamed from test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp)0
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ctor.pass.cpp46
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/decrement.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/increment.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ok.pass.cpp37
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/plus_minus_equal.pass.cpp57
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/comparisons.pass.cpp44
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.fail.cpp28
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp47
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/minus.pass.cpp58
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/plus.pass.cpp59
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp56
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.last/types.pass.cpp33
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ctor.pass.cpp47
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/day.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/month.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ok.pass.cpp55
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/comparisons.pass.cpp70
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/comparisons.pass.cpp43
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/ctor.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/month.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/ok.pass.cpp46
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp34
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp (renamed from test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.fail.cpp)20
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ctor.pass.cpp46
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/decrement.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/increment.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ok.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/plus_minus_equal.pass.cpp67
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/comparisons.pass.cpp47
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/literals.pass.cpp87
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp72
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/plus.pass.cpp72
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ctor.pass.cpp46
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/month.pass.cpp42
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ok.pass.cpp51
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/weekday_indexed.pass.cpp43
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/comparisons.pass.cpp86
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp36
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ctor.pass.cpp60
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/month.pass.cpp42
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ok.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/weekday_last.pass.cpp44
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/comparisons.pass.cpp73
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp37
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/types.pass.cpp27
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_day.pass.cpp108
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_day_last.pass.cpp107
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_weekday.pass.cpp115
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_weekday_last.pass.cpp107
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month.pass.cpp68
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_day.pass.cpp191
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_day_last.pass.cpp125
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday.pass.cpp145
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday_last.pass.cpp153
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ctor.pass.cpp61
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/index.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ok.pass.cpp49
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/weekday.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/comparisons.pass.cpp48
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp36
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ctor.pass.cpp47
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ok.pass.cpp37
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/weekday.pass.cpp33
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/comparisons.pass.cpp43
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp34
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp73
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.pass.cpp51
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp73
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/decrement.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ok.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/operator[].pass.cpp59
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp63
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/comparisons.pass.cpp42
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/literals.pass.cpp62
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp76
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/plus.pass.cpp70
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp56
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ctor.pass.cpp46
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/decrement.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/increment.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/is_leap.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ok.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus.pass.cpp50
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus_equal.pass.cpp57
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/comparisons.pass.cpp47
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.fail.cpp28
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp44
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/minus.pass.cpp62
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/plus.pass.cpp59
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp55
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ctor.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/month.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ok.pass.cpp50
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp64
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_year.pass.cpp65
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/year.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/comparisons.pass.cpp69
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp90
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp106
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp57
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp85
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.pass.cpp56
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp84
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp80
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/day.pass.cpp40
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/month.pass.cpp40
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp96
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp94
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp94
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp70
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_year.pass.cpp70
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/year.pass.cpp40
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/comparisons.pass.cpp118
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/minus.pass.cpp60
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp112
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp58
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ctor.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp51
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month_day_last.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ok.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp61
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp61
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp66
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_year.pass.cpp65
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/year.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/comparisons.pass.cpp87
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp91
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp122
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp37
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp95
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.pass.cpp64
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp94
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/index.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/month.pass.cpp40
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ok.pass.cpp75
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp74
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp74
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp80
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_year.pass.cpp80
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday_indexed.pass.cpp45
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/year.pass.cpp40
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/comparisons.pass.cpp113
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp100
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/plus.pass.cpp120
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp57
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ctor.pass.cpp52
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/month.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ok.pass.cpp73
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp61
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp69
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_month.pass.cpp75
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp76
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/weekday.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/year.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/comparisons.pass.cpp114
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/minus.pass.cpp93
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/plus.pass.cpp116
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/types.pass.cpp26
-rw-r--r--test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp35
-rw-r--r--test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp29
-rw-r--r--test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp35
-rw-r--r--test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp29
-rw-r--r--test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp7
-rw-r--r--test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp7
-rw-r--r--test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp7
-rw-r--r--test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp65
-rw-r--r--test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp64
-rw-r--r--test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp3
-rw-r--r--test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp25
-rw-r--r--test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp3
-rw-r--r--test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp6
-rw-r--r--test/std/utilities/time/time.duration/time.duration.special/min.pass.cpp6
-rw-r--r--test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp6
-rw-r--r--test/std/utilities/time/time.point/time.point.arithmetic/op_+=.pass.cpp20
-rw-r--r--test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp20
-rw-r--r--test/std/utilities/time/time.point/time.point.special/max.pass.cpp8
-rw-r--r--test/std/utilities/time/time.point/time.point.special/min.pass.cpp8
-rw-r--r--test/std/utilities/time/time.traits/time.traits.duration_values/max.pass.cpp11
-rw-r--r--test/std/utilities/time/time.traits/time.traits.duration_values/min.pass.cpp11
-rw-r--r--test/std/utilities/time/time.traits/time.traits.duration_values/zero.pass.cpp9
-rw-r--r--test/std/utilities/time/weeks.pass.cpp28
-rw-r--r--test/std/utilities/time/years.pass.cpp28
-rw-r--r--test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp3
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp1
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp1
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp8
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp4
-rw-r--r--test/std/utilities/type.index/type.index.hash/hash.pass.cpp1
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp5
-rw-r--r--test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp14
-rw-r--r--test/std/utilities/variant/variant.get/get_index.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.get/get_type.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.relops/relops.pass.cpp107
-rw-r--r--test/std/utilities/variant/variant.relops/relops_bool_conv.fail.cpp88
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp45
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp46
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp8
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp41
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp26
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp8
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp8
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp41
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp16
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp16
-rw-r--r--test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp13
-rw-r--r--test/std/utilities/variant/variant.visit/visit.pass.cpp13
-rw-r--r--test/support/any_helpers.h3
-rw-r--r--test/support/archetypes.hpp15
-rw-r--r--test/support/archetypes.ipp86
-rw-r--r--test/support/counting_predicates.hpp11
-rw-r--r--test/support/filesystem_dynamic_test_helper.py13
-rw-r--r--test/support/filesystem_test_helper.hpp46
-rw-r--r--test/support/min_allocator.h54
-rw-r--r--test/support/nasty_macros.hpp7
-rw-r--r--test/support/poisoned_hash_helper.hpp2
-rw-r--r--test/support/test_comparisons.h80
-rw-r--r--test/support/test_macros.h59
-rw-r--r--test/support/truncate_fp.h23
-rw-r--r--test/support/unique_ptr_test_helper.h1
-rwxr-xr-xutils/ci/macos-backdeployment.sh180
-rwxr-xr-xutils/ci/macos-trunk.sh153
-rwxr-xr-xutils/docker/build_docker_image.sh109
-rw-r--r--utils/docker/debian9/Dockerfile115
-rwxr-xr-xutils/docker/scripts/build_gcc.sh91
-rwxr-xr-xutils/docker/scripts/build_install_llvm.sh114
-rwxr-xr-xutils/docker/scripts/checkout_git.sh130
-rwxr-xr-xutils/docker/scripts/docker_start_buildbots.sh8
-rwxr-xr-xutils/docker/scripts/install_clang_packages.sh64
-rwxr-xr-xutils/docker/scripts/run_buildbot.sh62
-rw-r--r--utils/google-benchmark/.clang-format5
-rw-r--r--utils/google-benchmark/.gitignore12
-rw-r--r--utils/google-benchmark/.travis-libcxx-setup.sh28
-rw-r--r--utils/google-benchmark/.travis.yml199
-rw-r--r--utils/google-benchmark/.ycm_extra_conf.py115
-rw-r--r--utils/google-benchmark/AUTHORS1
-rw-r--r--utils/google-benchmark/CMakeLists.txt19
-rw-r--r--utils/google-benchmark/CONTRIBUTORS2
-rw-r--r--utils/google-benchmark/README.md170
-rw-r--r--utils/google-benchmark/WORKSPACE7
-rw-r--r--utils/google-benchmark/appveyor.yml50
-rw-r--r--utils/google-benchmark/cmake/CXXFeatureCheck.cmake10
-rw-r--r--utils/google-benchmark/cmake/GetGitVersion.cmake2
-rw-r--r--utils/google-benchmark/cmake/HandleGTest.cmake8
-rw-r--r--utils/google-benchmark/docs/tools.md99
-rw-r--r--utils/google-benchmark/include/benchmark/benchmark.h172
-rw-r--r--utils/google-benchmark/mingw.py320
-rw-r--r--utils/google-benchmark/src/benchmark.cc303
-rw-r--r--utils/google-benchmark/src/benchmark_api_internal.cc15
-rw-r--r--utils/google-benchmark/src/benchmark_api_internal.h11
-rw-r--r--utils/google-benchmark/src/benchmark_register.cc41
-rw-r--r--utils/google-benchmark/src/benchmark_runner.cc350
-rw-r--r--utils/google-benchmark/src/benchmark_runner.h51
-rw-r--r--utils/google-benchmark/src/colorprint.cc2
-rw-r--r--utils/google-benchmark/src/complexity.cc17
-rw-r--r--utils/google-benchmark/src/console_reporter.cc54
-rw-r--r--utils/google-benchmark/src/csv_reporter.cc14
-rw-r--r--utils/google-benchmark/src/cycleclock.h2
-rw-r--r--utils/google-benchmark/src/internal_macros.h14
-rw-r--r--utils/google-benchmark/src/json_reporter.cc45
-rw-r--r--utils/google-benchmark/src/reporter.cc20
-rw-r--r--utils/google-benchmark/src/sleep.cc2
-rw-r--r--utils/google-benchmark/src/statistics.cc37
-rw-r--r--utils/google-benchmark/src/string_util.h6
-rw-r--r--utils/google-benchmark/src/sysinfo.cc73
-rw-r--r--utils/google-benchmark/src/thread_manager.h2
-rw-r--r--utils/google-benchmark/src/timers.cc6
-rw-r--r--utils/google-benchmark/test/AssemblyTests.cmake46
-rw-r--r--utils/google-benchmark/test/CMakeLists.txt12
-rw-r--r--utils/google-benchmark/test/complexity_test.cc39
-rw-r--r--utils/google-benchmark/test/display_aggregates_only_test.cc43
-rw-r--r--utils/google-benchmark/test/memory_manager_test.cc42
-rw-r--r--utils/google-benchmark/test/output_test.h7
-rw-r--r--utils/google-benchmark/test/output_test_helper.cc88
-rw-r--r--utils/google-benchmark/test/register_benchmark_test.cc4
-rw-r--r--utils/google-benchmark/test/report_aggregates_only_test.cc39
-rw-r--r--utils/google-benchmark/test/reporter_output_test.cc365
-rw-r--r--utils/google-benchmark/test/skip_with_error_test.cc4
-rw-r--r--utils/google-benchmark/test/string_util_gtest.cc62
-rw-r--r--utils/google-benchmark/test/user_counters_tabular_test.cc118
-rw-r--r--utils/google-benchmark/test/user_counters_test.cc134
-rw-r--r--utils/google-benchmark/test/user_counters_thousands_test.cc161
-rwxr-xr-xutils/google-benchmark/tools/compare.py43
-rw-r--r--utils/google-benchmark/tools/compare_bench.py67
-rw-r--r--utils/google-benchmark/tools/gbench/Inputs/test3_run0.json26
-rw-r--r--utils/google-benchmark/tools/gbench/Inputs/test3_run1.json32
-rw-r--r--utils/google-benchmark/tools/gbench/report.py362
-rw-r--r--utils/google-benchmark/tools/gbench/util.py15
-rw-r--r--utils/libcxx/test/config.py104
-rw-r--r--utils/libcxx/test/format.py25
-rw-r--r--utils/libcxx/test/googlebenchmark.py122
-rw-r--r--utils/libcxx/test/target_info.py43
-rw-r--r--www/cxx1y_status.html9
-rw-r--r--www/cxx1z_status.html12
-rw-r--r--www/cxx2a_status.html93
-rw-r--r--www/index.html24
-rw-r--r--www/upcoming_meeting.html135
1057 files changed, 40275 insertions, 7092 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39ff0a29dcdf..a57e36fddcde 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
project(libcxx CXX C)
set(PACKAGE_NAME libcxx)
- set(PACKAGE_VERSION 7.0.0svn)
+ set(PACKAGE_VERSION 8.0.0svn)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
@@ -50,9 +50,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()
@@ -77,7 +82,12 @@ option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++fs.a"
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
# 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++")
@@ -111,15 +121,12 @@ cmake_dependent_option(LIBCXX_INSTALL_FILESYSTEM_LIBRARY
"Install libc++fs.a" ON
"LIBCXX_ENABLE_FILESYSTEM;LIBCXX_INSTALL_LIBRARY" OFF)
-if (FUCHSIA)
- set(DEFAULT_ABI_VERSION 2)
-else()
- set(DEFAULT_ABI_VERSION 1)
-endif()
-set(LIBCXX_ABI_VERSION ${DEFAULT_ABI_VERSION} CACHE STRING "ABI version of libc++.")
+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.")
+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_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
@@ -175,7 +182,7 @@ cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY
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_STATIC" OFF)
+ "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
@@ -276,6 +283,9 @@ 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
#===============================================================================
@@ -502,14 +512,16 @@ 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)
+if (LIBCXX_HAS_MUSL_LIBC OR LIBCXX_TARGETING_CLANG_CL)
# 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})
+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})
+mangle_name("LIBCXX_SUPPORTS_STD_COLON_${LIBCXX_STANDARD_VER}_FLAG" SUPPORTS_DIALECT_NAME_MSVC)
+if(NOT ${SUPPORTS_DIALECT_NAME} AND NOT ${SUPPORTS_DIALECT_NAME_MSVC})
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}")
endif()
@@ -544,11 +556,29 @@ 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)
+ -Werror=return-type -Wextra-semi)
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_compile_flags_if_supported(
-Wno-user-defined-literals
-Wno-covered-switch-default)
+ if (LIBCXX_TARGETING_CLANG_CL)
+ add_compile_flags_if_supported(
+ -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")
add_compile_flags_if_supported(
-Wno-literal-suffix
@@ -621,47 +651,67 @@ endif()
# Sanitizer flags =============================================================
-# 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")
+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 (LLVM_USE_SANITIZER AND NOT MSVC)
- add_flags_if_supported("-fno-omit-frame-pointer")
- add_flags_if_supported("-gline-tables-only")
+ 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")
- add_flags_if_supported("-gline-tables-only")
+ NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
+ append_flags_if_supported(SANITIZER_FLAGS "-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")
+ 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 (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)
+ elseif (USE_SANITIZER STREQUAL "Undefined")
+ append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
+ elseif (USE_SANITIZER STREQUAL "Thread")
+ append_flags(SANITIZER_FLAGS -fsanitize=thread)
else()
- message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
+ message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}")
endif()
- elseif(LLVM_USE_SANITIZER AND MSVC)
+ 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")
+endif()
+get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}")
+if (LIBCXX_STANDALONE_BUILD AND SANITIZER_FLAGS)
+ add_flags(${SANITIZER_FLAGS})
endif()
# Configuration file flags =====================================================
-if (NOT LIBCXX_ABI_VERSION EQUAL DEFAULT_ABI_VERSION)
+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(WARNING "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(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_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE)
config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN)
@@ -724,6 +774,18 @@ include_directories(include)
add_subdirectory(include)
add_subdirectory(lib)
+set(LIBCXX_TEST_DEPS "")
+
+if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
+ list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
+endif()
+if (LIBCXX_ENABLE_FILESYSTEM)
+ list(APPEND LIBCXX_TEST_DEPS cxx_filesystem)
+endif()
+
+if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
+ list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
+endif()
if (LIBCXX_INCLUDE_BENCHMARKS)
add_subdirectory(benchmarks)
diff --git a/LICENSE.TXT b/LICENSE.TXT
index c278f2c92833..190d9394d517 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -14,7 +14,7 @@ Full text of the relevant licenses is included below.
University of Illinois/NCSA
Open Source License
-Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT
+Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
diff --git a/appveyor-reqs-install.cmd b/appveyor-reqs-install.cmd
index a4160110aa5f..02c939ebc8c3 100644
--- a/appveyor-reqs-install.cmd
+++ b/appveyor-reqs-install.cmd
@@ -9,7 +9,7 @@ cd C:\projects\deps
:: Setup Compiler
::###########################################################################
if NOT EXIST llvm-installer.exe (
- appveyor DownloadFile http://prereleases.llvm.org/win-snapshots/LLVM-7.0.0-r325576-win32.exe -FileName llvm-installer.exe
+ appveyor DownloadFile https://prereleases.llvm.org/win-snapshots/LLVM-8.0.0-r345380-win32.exe -FileName llvm-installer.exe
)
if "%CLANG_VERSION%"=="ToT" (
START /WAIT llvm-installer.exe /S /D=C:\"Program Files\LLVM"
diff --git a/appveyor.yml b/appveyor.yml
index be69a555d778..0154abbffa9d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,14 +19,6 @@ environment:
MAKE_PROGRAM: ninja
APPVEYOR_SAVE_CACHE_ON_ERROR: true
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- CMAKE_OPTIONS: -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe
- CLANG_VERSION: 4
- MSVC_SETUP_PATH: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
- MSVC_SETUP_ARG: x86_amd64
- GENERATOR: Ninja
- MAKE_PROGRAM: ninja
- APPVEYOR_SAVE_CACHE_ON_ERROR: true
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
MINGW_PATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin
GENERATOR: MinGW Makefiles
MAKE_PROGRAM: mingw32-make
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
index f557d4aea39a..3823b87b39e0 100644
--- a/benchmarks/CMakeLists.txt
+++ b/benchmarks/CMakeLists.txt
@@ -11,17 +11,21 @@ set(BENCHMARK_LIBCXX_COMPILE_FLAGS
-isystem ${LIBCXX_SOURCE_DIR}/include
-L${LIBCXX_LIBRARY_DIR}
-Wl,-rpath,${LIBCXX_LIBRARY_DIR}
+ ${SANITIZER_FLAGS}
)
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
+ DEPENDS cxx cxx-headers
PREFIX benchmark-libcxx
SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx
@@ -67,8 +71,19 @@ add_custom_target(cxx-benchmarks)
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
- -std=c++17 -O2
+ ${BENCHMARK_DIALECT_FLAG} -O2
-I${BENCHMARK_LIBCXX_INSTALL}/include
-I${LIBCXX_SOURCE_DIR}/test/support
)
@@ -76,11 +91,18 @@ set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
-nostdinc++
-isystem ${LIBCXX_SOURCE_DIR}/include
${BENCHMARK_TEST_COMPILE_FLAGS}
+ ${SANITIZER_FLAGS}
-Wno-user-defined-literals
)
+if (LIBCXX_NEEDS_SITE_CONFIG)
+ list(APPEND BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
+ -include "${LIBCXX_BINARY_DIR}/__config_site")
+endif()
+
set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS
-nodefaultlibs
-L${BENCHMARK_LIBCXX_INSTALL}/lib/
+ ${SANITIZER_FLAGS}
)
set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS
${BENCHMARK_NATIVE_TARGET_FLAGS}
@@ -95,10 +117,25 @@ 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)
-macro(add_benchmark_test name source_file)
+
+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()
+endif()
+
+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 google-benchmark-libcxx)
+ add_dependencies(${libcxx_target} cxx cxx-headers google-benchmark-libcxx)
add_dependencies(cxx-benchmarks ${libcxx_target})
if (LIBCXX_ENABLE_SHARED)
target_link_libraries(${libcxx_target} cxx_shared)
@@ -108,7 +145,13 @@ macro(add_benchmark_test name source_file)
if (TARGET cxx_experimental)
target_link_libraries(${libcxx_target} cxx_experimental)
endif()
+ if (TARGET cxx_filesystem)
+ target_link_libraries(${libcxx_target} cxx_filesystem)
+ endif()
target_link_libraries(${libcxx_target} -lbenchmark)
+ if (LLVM_USE_SANITIZER)
+ target_link_libraries(${libcxx_target} -ldl)
+ endif()
set_target_properties(${libcxx_target}
PROPERTIES
OUTPUT_NAME "${name}.libcxx.out"
@@ -116,15 +159,19 @@ macro(add_benchmark_test name source_file)
COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"
LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}")
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})
add_dependencies(${native_target} google-benchmark-native
google-benchmark-libcxx)
target_link_libraries(${native_target} -lbenchmark)
if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
- target_link_libraries(${native_target} -lstdc++fs)
+ target_link_libraries(${native_target} ${LIBSTDCXX_FILESYSTEM_LIB})
elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++")
- target_link_libraries(${native_target} -lc++experimental)
+ target_link_libraries(${native_target} -lc++fs -lc++experimental)
endif()
if (LIBCXX_HAS_PTHREAD_LIB)
target_link_libraries(${native_target} -pthread)
@@ -138,7 +185,7 @@ macro(add_benchmark_test name source_file)
COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}"
LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}")
endif()
-endmacro()
+endfunction()
#==============================================================================
@@ -155,3 +202,23 @@ foreach(test_path ${BENCHMARK_TESTS})
endif()
add_benchmark_test(${test_name} ${test_file})
endforeach()
+
+if (LIBCXX_INCLUDE_TESTS)
+ include(AddLLVM)
+
+ if (NOT DEFINED LIBCXX_TEST_DEPS)
+ message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
+ endif()
+
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
+
+ set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}")
+
+ add_lit_target(check-cxx-benchmarks
+ "Running libcxx benchmarks tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS}
+ ARGS ${BENCHMARK_LIT_ARGS})
+endif()
diff --git a/benchmarks/CartesianBenchmarks.hpp b/benchmarks/CartesianBenchmarks.hpp
new file mode 100644
index 000000000000..88a994c55512
--- /dev/null
+++ b/benchmarks/CartesianBenchmarks.hpp
@@ -0,0 +1,135 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace internal {
+
+template <class D, class E, size_t I>
+struct EnumValue : std::integral_constant<E, static_cast<E>(I)> {
+ static std::string name() { return std::string("_") + D::Names[I]; }
+};
+
+template <class D, class E, size_t ...Idxs>
+constexpr auto makeEnumValueTuple(std::index_sequence<Idxs...>) {
+ return std::make_tuple(EnumValue<D, E, Idxs>{}...);
+}
+
+template <class B>
+static auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
+ return Bench.skip();
+}
+template <class B>
+static auto skip(const B& Bench, char) {
+ return false;
+}
+
+template <class B, class Args, size_t... Is>
+void makeBenchmarkFromValuesImpl(const Args& A, std::index_sequence<Is...>) {
+ for (auto& V : A) {
+ B Bench{std::get<Is>(V)...};
+ if (!internal::skip(Bench, 0)) {
+ benchmark::RegisterBenchmark(Bench.name().c_str(),
+ [=](benchmark::State& S) { Bench.run(S); });
+ }
+ }
+}
+
+template <class B, class... Args>
+void makeBenchmarkFromValues(const std::vector<std::tuple<Args...> >& A) {
+ makeBenchmarkFromValuesImpl<B>(A, std::index_sequence_for<Args...>());
+}
+
+template <template <class...> class B, class Args, class... U>
+void makeBenchmarkImpl(const Args& A, std::tuple<U...> t) {
+ makeBenchmarkFromValues<B<U...> >(A);
+}
+
+template <template <class...> class B, class Args, class... U,
+ class... T, class... Tuples>
+void makeBenchmarkImpl(const Args& A, std::tuple<U...>, std::tuple<T...>,
+ Tuples... rest) {
+ (internal::makeBenchmarkImpl<B>(A, std::tuple<U..., T>(), rest...), ...);
+}
+
+template <class R, class T>
+void allValueCombinations(R& Result, const T& Final) {
+ return Result.push_back(Final);
+}
+
+template <class R, class T, class V, class... Vs>
+void allValueCombinations(R& Result, const T& Prev, const V& Value,
+ const Vs&... Values) {
+ for (const auto& E : Value) {
+ allValueCombinations(Result, std::tuple_cat(Prev, std::make_tuple(E)),
+ Values...);
+ }
+}
+
+} // namespace internal
+
+// CRTP class that enables using enum types as a dimension for
+// makeCartesianProductBenchmark below.
+// The type passed to `B` will be a std::integral_constant<E, e>, with the
+// additional static function `name()` that returns the stringified name of the
+// label.
+//
+// Eg:
+// enum class MyEnum { A, B };
+// struct AllMyEnum : EnumValuesAsTuple<AllMyEnum, MyEnum, 2> {
+// static constexpr absl::string_view Names[] = {"A", "B"};
+// };
+template <class Derived, class EnumType, size_t NumLabels>
+using EnumValuesAsTuple =
+ decltype(internal::makeEnumValueTuple<Derived, EnumType>(
+ std::make_index_sequence<NumLabels>{}));
+
+// Instantiates B<T0, T1, ..., TN> where <Ti...> are the combinations in the
+// cartesian product of `Tuples...`, and pass (arg0, ..., argN) as constructor
+// arguments where `(argi...)` are the combination in the cartesian product of
+// the runtime values of `A...`.
+// B<T...> requires:
+// - std::string name(args...): The name of the benchmark.
+// - void run(benchmark::State&, args...): The body of the benchmark.
+// It can also optionally provide:
+// - bool skip(args...): When `true`, skips the combination. Default is false.
+//
+// Returns int to facilitate registration. The return value is unspecified.
+template <template <class...> class B, class... Tuples, class... Args>
+int makeCartesianProductBenchmark(const Args&... A) {
+ std::vector<std::tuple<typename Args::value_type...> > V;
+ internal::allValueCombinations(V, std::tuple<>(), A...);
+ internal::makeBenchmarkImpl<B>(V, std::tuple<>(), Tuples()...);
+ return 0;
+}
+
+template <class B, class... Args>
+int makeCartesianProductBenchmark(const Args&... A) {
+ std::vector<std::tuple<typename Args::value_type...> > V;
+ internal::allValueCombinations(V, std::tuple<>(), A...);
+ internal::makeBenchmarkFromValues<B>(V);
+ return 0;
+}
+
+// When `opaque` is true, this function hides the runtime state of `value` from
+// the optimizer.
+// It returns `value`.
+template <class T>
+TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) {
+ if (opaque) benchmark::DoNotOptimize(value);
+ return value;
+}
+
diff --git a/benchmarks/algorithms.bench.cpp b/benchmarks/algorithms.bench.cpp
index 86315390e0d2..eee8a4da2ab0 100644
--- a/benchmarks/algorithms.bench.cpp
+++ b/benchmarks/algorithms.bench.cpp
@@ -1,62 +1,270 @@
-#include <unordered_set>
-#include <vector>
+
+#include <algorithm>
#include <cstdint>
+#include <map>
+#include <random>
+#include <string>
+#include <utility>
+#include <vector>
-#include "benchmark/benchmark.h"
+#include "CartesianBenchmarks.hpp"
#include "GenerateInput.hpp"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class ValueType { Uint32, String };
+struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 2> {
+ static constexpr const char* Names[] = {"uint32", "string"};
+};
+
+template <class V>
+using Value =
+ std::conditional_t<V() == ValueType::Uint32, uint32_t, std::string>;
+
+enum class Order {
+ Random,
+ Ascending,
+ Descending,
+ SingleElement,
+ PipeOrgan,
+ Heap
+};
+struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 6> {
+ static constexpr const char* Names[] = {"Random", "Ascending",
+ "Descending", "SingleElement",
+ "PipeOrgan", "Heap"};
+};
+
+void fillValues(std::vector<uint32_t>& V, size_t N, Order O) {
+ if (O == Order::SingleElement) {
+ V.resize(N, 0);
+ } else {
+ while (V.size() < N)
+ V.push_back(V.size());
+ }
+}
+
+void fillValues(std::vector<std::string>& V, size_t N, Order O) {
+
+ if (O == Order::SingleElement) {
+ V.resize(N, getRandomString(1024));
+ } else {
+ while (V.size() < N)
+ V.push_back(getRandomString(1024));
+ }
+}
+
+template <class T>
+void sortValues(T& V, Order O) {
+ assert(std::is_sorted(V.begin(), V.end()));
+ switch (O) {
+ case Order::Random: {
+ std::random_device R;
+ std::mt19937 M(R());
+ std::shuffle(V.begin(), V.end(), M);
+ break;
+ }
+ case Order::Ascending:
+ std::sort(V.begin(), V.end());
+ break;
+ case Order::Descending:
+ std::sort(V.begin(), V.end(), std::greater<>());
+ break;
+ case Order::SingleElement:
+ // Nothing to do
+ break;
+ case Order::PipeOrgan:
+ std::sort(V.begin(), V.end());
+ std::reverse(V.begin() + V.size() / 2, V.end());
+ break;
+ case Order::Heap:
+ std::make_heap(V.begin(), V.end());
+ break;
+ }
+}
+
+template <class ValueType>
+std::vector<std::vector<Value<ValueType> > > 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::pair<size_t, Order>, std::vector<Value<ValueType> > >
+ Cached;
-constexpr std::size_t TestNumInputs = 1024;
-
-template <class GenInputs>
-void BM_Sort(benchmark::State& st, GenInputs gen) {
- using ValueType = typename decltype(gen(0))::value_type;
- const auto in = gen(st.range(0));
- std::vector<ValueType> inputs[5];
- auto reset_inputs = [&]() {
- for (auto& C : inputs) {
- C = in;
- benchmark::DoNotOptimize(C.data());
- }
- };
- reset_inputs();
- while (st.KeepRunning()) {
- for (auto& I : inputs) {
- std::sort(I.data(), I.data() + I.size());
- benchmark::DoNotOptimize(I.data());
- }
- st.PauseTiming();
- reset_inputs();
- benchmark::ClobberMemory();
- st.ResumeTiming();
+ 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 };
+}
+
+template <class T, class U>
+TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies,
+ U& Orig) {
+ state.PauseTiming();
+ for (auto& Copy : Copies)
+ Copy = Orig;
+ state.ResumeTiming();
+}
+
+template <class ValueType, class F>
+void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
+ bool CountElements, F f) {
+ auto Copies = makeOrderedValues<ValueType>(Quantity, O);
+ const auto Orig = Copies[0];
+
+ const size_t Batch = CountElements ? Copies.size() * Quantity : Copies.size();
+ while (state.KeepRunningBatch(Batch)) {
+ for (auto& Copy : Copies) {
+ f(Copy);
+ benchmark::DoNotOptimize(Copy);
}
+ resetCopies(state, Copies, Orig);
+ }
}
-BENCHMARK_CAPTURE(BM_Sort, random_uint32,
- getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+template <class ValueType, class Order>
+struct Sort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::sort(Copy.begin(), Copy.end());
+ });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_Sort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+
+template <class ValueType, class Order>
+struct StableSort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::stable_sort(Copy.begin(), Copy.end());
+ });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+
+template <class ValueType, class Order>
+struct MakeHeap {
+ size_t Quantity;
-BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_uint32,
- getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::make_heap(Copy.begin(), Copy.end());
+ });
+ }
-BENCHMARK_CAPTURE(BM_Sort, sorted_descending_uint32,
- getReverseSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+ std::string name() const {
+ return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_Sort, single_element_uint32,
- getDuplicateIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+template <class ValueType>
+struct SortHeap {
+ size_t Quantity;
-BENCHMARK_CAPTURE(BM_Sort, pipe_organ_uint32,
- getPipeOrganIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order::Heap, false,
+ [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
+ }
-BENCHMARK_CAPTURE(BM_Sort, random_strings,
- getRandomStringInputs)->Arg(TestNumInputs);
+ std::string name() const {
+ return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_strings,
- getSortedStringInputs)->Arg(TestNumInputs);
+template <class ValueType, class Order>
+struct MakeThenSortHeap {
+ size_t Quantity;
-BENCHMARK_CAPTURE(BM_Sort, sorted_descending_strings,
- getReverseSortedStringInputs)->Arg(TestNumInputs);
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::make_heap(Copy.begin(), Copy.end());
+ std::sort_heap(Copy.begin(), Copy.end());
+ });
+ }
-BENCHMARK_CAPTURE(BM_Sort, single_element_strings,
- getDuplicateStringInputs)->Arg(TestNumInputs);
+ std::string name() const {
+ return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+template <class ValueType, class Order>
+struct PushHeap {
+ size_t Quantity;
-BENCHMARK_MAIN();
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](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; }
+
+ std::string name() const {
+ return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+
+template <class ValueType>
+struct PopHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](auto& Copy) {
+ for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
+ std::pop_heap(B, I);
+ }
+ });
+ }
+
+ std::string name() const {
+ return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
+ 1 << 8, 1 << 10, 1 << 14, 1 << 18};
+ makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
+ makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(
+ Quantities);
+ makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
+ makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
+ makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(
+ Quantities);
+ makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
+ makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/algorithms.partition_point.bench.cpp b/benchmarks/algorithms.partition_point.bench.cpp
new file mode 100644
index 000000000000..00a3bb272672
--- /dev/null
+++ b/benchmarks/algorithms.partition_point.bench.cpp
@@ -0,0 +1,124 @@
+#include <array>
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <tuple>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+
+#include "CartesianBenchmarks.hpp"
+#include "GenerateInput.hpp"
+
+namespace {
+
+template <typename I, typename N>
+std::array<I, 10> every_10th_percentile_N(I first, N n) {
+ N step = n / 10;
+ std::array<I, 10> res;
+
+ for (size_t i = 0; i < 10; ++i) {
+ res[i] = first;
+ std::advance(first, step);
+ }
+
+ return res;
+}
+
+template <class IntT>
+struct TestIntBase {
+ static std::vector<IntT> generateInput(size_t size) {
+ std::vector<IntT> Res(size);
+ std::generate(Res.begin(), Res.end(),
+ [] { return getRandomInteger<IntT>(); });
+ return Res;
+ }
+};
+
+struct TestInt32 : TestIntBase<std::int32_t> {
+ static constexpr const char* Name = "TestInt32";
+};
+
+struct TestInt64 : TestIntBase<std::int64_t> {
+ static constexpr const char* Name = "TestInt64";
+};
+
+struct TestUint32 : TestIntBase<std::uint32_t> {
+ static constexpr const char* Name = "TestUint32";
+};
+
+struct TestMediumString {
+ static constexpr const char* Name = "TestMediumString";
+ static constexpr size_t StringSize = 32;
+
+ static std::vector<std::string> generateInput(size_t size) {
+ std::vector<std::string> Res(size);
+ std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); });
+ return Res;
+ }
+};
+
+using AllTestTypes = std::tuple<TestInt32, TestInt64, TestUint32, TestMediumString>;
+
+struct LowerBoundAlg {
+ template <class I, class V>
+ I operator()(I first, I last, const V& value) const {
+ return std::lower_bound(first, last, value);
+ }
+
+ static constexpr const char* Name = "LowerBoundAlg";
+};
+
+struct UpperBoundAlg {
+ template <class I, class V>
+ I operator()(I first, I last, const V& value) const {
+ return std::upper_bound(first, last, value);
+ }
+
+ static constexpr const char* Name = "UpperBoundAlg";
+};
+
+struct EqualRangeAlg {
+ template <class I, class V>
+ std::pair<I, I> operator()(I first, I last, const V& value) const {
+ return std::equal_range(first, last, value);
+ }
+
+ static constexpr const char* Name = "EqualRangeAlg";
+};
+
+using AllAlgs = std::tuple<LowerBoundAlg, UpperBoundAlg, EqualRangeAlg>;
+
+template <class Alg, class TestType>
+struct PartitionPointBench {
+ size_t Quantity;
+
+ std::string name() const {
+ return std::string("PartitionPointBench_") + Alg::Name + "_" +
+ TestType::Name + '/' + std::to_string(Quantity);
+ }
+
+ void run(benchmark::State& state) const {
+ auto Data = TestType::generateInput(Quantity);
+ std::sort(Data.begin(), Data.end());
+ auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size());
+
+ for (auto _ : state) {
+ for (auto Test : Every10Percentile)
+ benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test));
+ }
+ }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ const std::vector<size_t> Quantities = {1 << 8, 1 << 10, 1 << 20};
+ makeCartesianProductBenchmark<PartitionPointBench, AllAlgs, AllTestTypes>(
+ Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/function.bench.cpp b/benchmarks/function.bench.cpp
new file mode 100644
index 000000000000..4f0e1fd80fa3
--- /dev/null
+++ b/benchmarks/function.bench.cpp
@@ -0,0 +1,232 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "CartesianBenchmarks.hpp"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class FunctionType {
+ Null,
+ FunctionPointer,
+ MemberFunctionPointer,
+ MemberPointer,
+ SmallTrivialFunctor,
+ SmallNonTrivialFunctor,
+ LargeTrivialFunctor,
+ LargeNonTrivialFunctor
+};
+
+struct AllFunctionTypes : EnumValuesAsTuple<AllFunctionTypes, FunctionType, 8> {
+ static constexpr const char* Names[] = {"Null",
+ "FuncPtr",
+ "MemFuncPtr",
+ "MemPtr",
+ "SmallTrivialFunctor",
+ "SmallNonTrivialFunctor",
+ "LargeTrivialFunctor",
+ "LargeNonTrivialFunctor"};
+};
+
+enum class Opacity { kOpaque, kTransparent };
+
+struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
+ static constexpr const char* Names[] = {"Opaque", "Transparent"};
+};
+
+struct S {
+ int function() const { return 0; }
+ int field = 0;
+};
+
+int FunctionWithS(const S*) { return 0; }
+
+struct SmallTrivialFunctor {
+ int operator()(const S*) const { return 0; }
+};
+struct SmallNonTrivialFunctor {
+ SmallNonTrivialFunctor() {}
+ SmallNonTrivialFunctor(const SmallNonTrivialFunctor&) {}
+ ~SmallNonTrivialFunctor() {}
+ int operator()(const S*) const { return 0; }
+};
+struct LargeTrivialFunctor {
+ LargeTrivialFunctor() {
+ // Do not spend time initializing the padding.
+ }
+ int padding[16];
+ int operator()(const S*) const { return 0; }
+};
+struct LargeNonTrivialFunctor {
+ int padding[16];
+ LargeNonTrivialFunctor() {
+ // Do not spend time initializing the padding.
+ }
+ LargeNonTrivialFunctor(const LargeNonTrivialFunctor&) {}
+ ~LargeNonTrivialFunctor() {}
+ int operator()(const S*) const { return 0; }
+};
+
+using Function = std::function<int(const S*)>;
+
+TEST_ALWAYS_INLINE
+inline Function MakeFunction(FunctionType type, bool opaque = false) {
+ switch (type) {
+ case FunctionType::Null:
+ return nullptr;
+ case FunctionType::FunctionPointer:
+ return maybeOpaque(FunctionWithS, opaque);
+ case FunctionType::MemberFunctionPointer:
+ return maybeOpaque(&S::function, opaque);
+ case FunctionType::MemberPointer:
+ return maybeOpaque(&S::field, opaque);
+ case FunctionType::SmallTrivialFunctor:
+ return maybeOpaque(SmallTrivialFunctor{}, opaque);
+ case FunctionType::SmallNonTrivialFunctor:
+ return maybeOpaque(SmallNonTrivialFunctor{}, opaque);
+ case FunctionType::LargeTrivialFunctor:
+ return maybeOpaque(LargeTrivialFunctor{}, opaque);
+ case FunctionType::LargeNonTrivialFunctor:
+ return maybeOpaque(LargeNonTrivialFunctor{}, opaque);
+ }
+}
+
+template <class Opacity, class FunctionType>
+struct ConstructAndDestroy {
+ static void run(benchmark::State& state) {
+ for (auto _ : state) {
+ if (Opacity() == ::Opacity::kOpaque) {
+ benchmark::DoNotOptimize(MakeFunction(FunctionType(), true));
+ } else {
+ MakeFunction(FunctionType());
+ }
+ }
+ }
+
+ static std::string name() {
+ return "BM_ConstructAndDestroy" + FunctionType::name() + Opacity::name();
+ }
+};
+
+template <class FunctionType>
+struct Copy {
+ static void run(benchmark::State& state) {
+ auto value = MakeFunction(FunctionType());
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(value);
+ auto copy = value; // NOLINT
+ benchmark::DoNotOptimize(copy);
+ }
+ }
+
+ static std::string name() { return "BM_Copy" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct Move {
+ static void run(benchmark::State& state) {
+ Function values[2] = {MakeFunction(FunctionType())};
+ int i = 0;
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(values);
+ benchmark::DoNotOptimize(values[i ^ 1] = std::move(values[i]));
+ i ^= 1;
+ }
+ }
+
+ static std::string name() {
+ return "BM_Move" + FunctionType::name();
+ }
+};
+
+template <class Function1, class Function2>
+struct Swap {
+ static void run(benchmark::State& state) {
+ Function values[2] = {MakeFunction(Function1()), MakeFunction(Function2())};
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(values);
+ values[0].swap(values[1]);
+ }
+ }
+
+ static bool skip() { return Function1() > Function2(); }
+
+ static std::string name() {
+ return "BM_Swap" + Function1::name() + Function2::name();
+ }
+};
+
+template <class FunctionType>
+struct OperatorBool {
+ static void run(benchmark::State& state) {
+ auto f = MakeFunction(FunctionType());
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(f);
+ benchmark::DoNotOptimize(static_cast<bool>(f));
+ }
+ }
+
+ static std::string name() { return "BM_OperatorBool" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct Invoke {
+ static void run(benchmark::State& state) {
+ S s;
+ const auto value = MakeFunction(FunctionType());
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(value);
+ benchmark::DoNotOptimize(value(&s));
+ }
+ }
+
+ static bool skip() { return FunctionType() == ::FunctionType::Null; }
+
+ static std::string name() { return "BM_Invoke" + FunctionType::name(); }
+};
+
+template <class FunctionType>
+struct InvokeInlined {
+ static void run(benchmark::State& state) {
+ S s;
+ for (auto _ : state) {
+ MakeFunction(FunctionType())(&s);
+ }
+ }
+
+ static bool skip() { return FunctionType() == ::FunctionType::Null; }
+
+ static std::string name() {
+ return "BM_InvokeInlined" + FunctionType::name();
+ }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ makeCartesianProductBenchmark<ConstructAndDestroy, AllOpacity,
+ AllFunctionTypes>();
+ makeCartesianProductBenchmark<Copy, AllFunctionTypes>();
+ makeCartesianProductBenchmark<Move, AllFunctionTypes>();
+ makeCartesianProductBenchmark<Swap, AllFunctionTypes, AllFunctionTypes>();
+ makeCartesianProductBenchmark<OperatorBool, AllFunctionTypes>();
+ makeCartesianProductBenchmark<Invoke, AllFunctionTypes>();
+ makeCartesianProductBenchmark<InvokeInlined, AllFunctionTypes>();
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/lit.cfg.py b/benchmarks/lit.cfg.py
new file mode 100644
index 000000000000..84857d570d7a
--- /dev/null
+++ b/benchmarks/lit.cfg.py
@@ -0,0 +1,23 @@
+# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
+# Configuration file for the 'lit' test runner.
+import os
+import site
+
+site.addsitedir(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'utils'))
+from libcxx.test.googlebenchmark import GoogleBenchmark
+
+# Tell pylint that we know config and lit_config exist somewhere.
+if 'PYLINT_IMPORT' in os.environ:
+ config = object()
+ lit_config = object()
+
+# name: The name of this test suite.
+config.name = 'libc++ benchmarks'
+config.suffixes = []
+
+config.test_exec_root = os.path.join(config.libcxx_obj_root, 'benchmarks')
+config.test_source_root = config.test_exec_root
+
+config.test_format = GoogleBenchmark(test_sub_dirs='.',
+ test_suffix='.libcxx.out',
+ benchmark_args=config.benchmark_args) \ No newline at end of file
diff --git a/benchmarks/lit.site.cfg.py.in b/benchmarks/lit.site.cfg.py.in
new file mode 100644
index 000000000000..e3ce8b22263e
--- /dev/null
+++ b/benchmarks/lit.site.cfg.py.in
@@ -0,0 +1,10 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
+config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@"
+config.benchmark_args = "@LIBCXX_BENCHMARK_TEST_ARGS@".split(';')
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/benchmarks/lit.cfg.py") \ No newline at end of file
diff --git a/benchmarks/ordered_set.bench.cpp b/benchmarks/ordered_set.bench.cpp
new file mode 100644
index 000000000000..b2ef0725b7ba
--- /dev/null
+++ b/benchmarks/ordered_set.bench.cpp
@@ -0,0 +1,249 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <random>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "CartesianBenchmarks.hpp"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
+
+namespace {
+
+enum class HitType { Hit, Miss };
+
+struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> {
+ static constexpr const char* Names[] = {"Hit", "Miss"};
+};
+
+enum class AccessPattern { Ordered, Random };
+
+struct AllAccessPattern
+ : EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> {
+ static constexpr const char* Names[] = {"Ordered", "Random"};
+};
+
+void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) {
+ if (AP == AccessPattern::Random) {
+ std::random_device R;
+ std::mt19937 M(R());
+ std::shuffle(std::begin(Keys), std::end(Keys), M);
+ }
+}
+
+struct TestSets {
+ std::vector<std::set<uint64_t> > Sets;
+ std::vector<uint64_t> Keys;
+};
+
+TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit,
+ AccessPattern Access) {
+ TestSets R;
+ R.Sets.resize(1);
+
+ for (uint64_t I = 0; I < TableSize; ++I) {
+ R.Sets[0].insert(2 * I);
+ R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1);
+ }
+ R.Sets.resize(NumTables, R.Sets[0]);
+ sortKeysBy(R.Keys, Access);
+
+ return R;
+}
+
+struct Base {
+ size_t TableSize;
+ size_t NumTables;
+ Base(size_t T, size_t N) : TableSize(T), NumTables(N) {}
+
+ bool skip() const {
+ size_t Total = TableSize * NumTables;
+ return Total < 100 || Total > 1000000;
+ }
+
+ std::string baseName() const {
+ return "_TableSize" + std::to_string(TableSize) + "_NumTables" +
+ std::to_string(NumTables);
+ }
+};
+
+template <class Access>
+struct Create : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ std::vector<uint64_t> Keys(TableSize);
+ std::iota(Keys.begin(), Keys.end(), uint64_t{0});
+ sortKeysBy(Keys, Access());
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ std::vector<std::set<uint64_t>> Sets(NumTables);
+ for (auto K : Keys) {
+ for (auto& Set : Sets) {
+ benchmark::DoNotOptimize(Set.insert(K));
+ }
+ }
+ }
+ }
+
+ std::string name() const {
+ return "BM_Create" + Access::name() + baseName();
+ }
+};
+
+template <class Hit, class Access>
+struct Find : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto K : Data.Keys) {
+ for (auto& Set : Data.Sets) {
+ benchmark::DoNotOptimize(Set.find(K));
+ }
+ }
+ }
+ }
+
+ std::string name() const {
+ return "BM_Find" + Hit::name() + Access::name() + baseName();
+ }
+};
+
+template <class Hit, class Access>
+struct FindNeEnd : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto K : Data.Keys) {
+ for (auto& Set : Data.Sets) {
+ benchmark::DoNotOptimize(Set.find(K) != Set.end());
+ }
+ }
+ }
+ }
+
+ std::string name() const {
+ return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName();
+ }
+};
+
+template <class Access>
+struct InsertHit : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access());
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto K : Data.Keys) {
+ for (auto& Set : Data.Sets) {
+ benchmark::DoNotOptimize(Set.insert(K));
+ }
+ }
+ }
+ }
+
+ std::string name() const {
+ return "BM_InsertHit" + Access::name() + baseName();
+ }
+};
+
+template <class Access>
+struct InsertMissAndErase : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access());
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto K : Data.Keys) {
+ for (auto& Set : Data.Sets) {
+ benchmark::DoNotOptimize(Set.erase(Set.insert(K).first));
+ }
+ }
+ }
+ }
+
+ std::string name() const {
+ return "BM_InsertMissAndErase" + Access::name() + baseName();
+ }
+};
+
+struct IterateRangeFor : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
+ AccessPattern::Ordered);
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto& Set : Data.Sets) {
+ for (auto& V : Set) {
+ benchmark::DoNotOptimize(V);
+ }
+ }
+ }
+ }
+
+ std::string name() const { return "BM_IterateRangeFor" + baseName(); }
+};
+
+struct IterateBeginEnd : Base {
+ using Base::Base;
+
+ void run(benchmark::State& State) const {
+ auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
+ AccessPattern::Ordered);
+
+ while (State.KeepRunningBatch(TableSize * NumTables)) {
+ for (auto& Set : Data.Sets) {
+ for (auto it = Set.begin(); it != Set.end(); ++it) {
+ benchmark::DoNotOptimize(*it);
+ }
+ }
+ }
+ }
+
+ std::string name() const { return "BM_IterateBeginEnd" + baseName(); }
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000};
+ const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000};
+
+ makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables);
+ makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>(
+ TableSize, NumTables);
+ makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>(
+ TableSize, NumTables);
+ makeCartesianProductBenchmark<InsertHit, AllAccessPattern>(
+ TableSize, NumTables);
+ makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>(
+ TableSize, NumTables);
+ makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables);
+ makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/string.bench.cpp b/benchmarks/string.bench.cpp
index 8a09e738d9b6..b8f97e6e2c12 100644
--- a/benchmarks/string.bench.cpp
+++ b/benchmarks/string.bench.cpp
@@ -1,9 +1,12 @@
-#include <unordered_set>
-#include <vector>
+
#include <cstdint>
+#include <new>
+#include <vector>
-#include "benchmark/benchmark.h"
+#include "CartesianBenchmarks.hpp"
#include "GenerateInput.hpp"
+#include "benchmark/benchmark.h"
+#include "test_macros.h"
constexpr std::size_t MAX_STRING_LEN = 8 << 14;
@@ -11,7 +14,7 @@ constexpr std::size_t MAX_STRING_LEN = 8 << 14;
static void BM_StringFindNoMatch(benchmark::State &state) {
std::string s1(state.range(0), '-');
std::string s2(8, '*');
- while (state.KeepRunning())
+ for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
@@ -20,7 +23,7 @@ BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
static void BM_StringFindAllMatch(benchmark::State &state) {
std::string s1(MAX_STRING_LEN, '-');
std::string s2(state.range(0), '-');
- while (state.KeepRunning())
+ for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindAllMatch)->Range(1, MAX_STRING_LEN);
@@ -30,7 +33,7 @@ static void BM_StringFindMatch1(benchmark::State &state) {
std::string s1(MAX_STRING_LEN / 2, '*');
s1 += std::string(state.range(0), '-');
std::string s2(state.range(0), '-');
- while (state.KeepRunning())
+ for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindMatch1)->Range(1, MAX_STRING_LEN / 4);
@@ -41,30 +44,332 @@ static void BM_StringFindMatch2(benchmark::State &state) {
s1 += std::string(state.range(0), '-');
s1 += std::string(state.range(0), '*');
std::string s2(state.range(0), '-');
- while (state.KeepRunning())
+ for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindMatch2)->Range(1, MAX_STRING_LEN / 4);
static void BM_StringCtorDefault(benchmark::State &state) {
- while (state.KeepRunning()) {
- for (unsigned I=0; I < 1000; ++I) {
- std::string Default;
- benchmark::DoNotOptimize(Default.c_str());
- }
+ for (auto _ : state) {
+ std::string Default;
+ benchmark::DoNotOptimize(Default);
}
}
BENCHMARK(BM_StringCtorDefault);
-static void BM_StringCtorCStr(benchmark::State &state) {
- std::string Input = getRandomString(state.range(0));
- const char *Str = Input.c_str();
- benchmark::DoNotOptimize(Str);
- while (state.KeepRunning()) {
- std::string Tmp(Str);
- benchmark::DoNotOptimize(Tmp.c_str());
+enum class Length { Empty, Small, Large, Huge };
+struct AllLengths : EnumValuesAsTuple<AllLengths, Length, 4> {
+ static constexpr const char* Names[] = {"Empty", "Small", "Large", "Huge"};
+};
+
+enum class Opacity { Opaque, Transparent };
+struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
+ static constexpr const char* Names[] = {"Opaque", "Transparent"};
+};
+
+enum class DiffType { Control, ChangeFirst, ChangeMiddle, ChangeLast };
+struct AllDiffTypes : EnumValuesAsTuple<AllDiffTypes, DiffType, 4> {
+ static constexpr const char* Names[] = {"Control", "ChangeFirst",
+ "ChangeMiddle", "ChangeLast"};
+};
+
+TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
+ switch (D) {
+ case DiffType::Control:
+ return "0123456";
+ case DiffType::ChangeFirst:
+ return "-123456";
+ case DiffType::ChangeMiddle:
+ return "012-456";
+ case DiffType::ChangeLast:
+ return "012345-";
+ }
+}
+
+TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
+#define LARGE_STRING_FIRST "123456789012345678901234567890"
+#define LARGE_STRING_SECOND "234567890123456789012345678901"
+ switch (D) {
+ case DiffType::Control:
+ return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
+ case DiffType::ChangeFirst:
+ return "-" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
+ case DiffType::ChangeMiddle:
+ return "0" LARGE_STRING_FIRST "-" LARGE_STRING_SECOND "2";
+ case DiffType::ChangeLast:
+ return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "-";
+ }
+}
+
+TEST_ALWAYS_INLINE const char* getHugeString(DiffType D) {
+#define HUGE_STRING0 "0123456789"
+#define HUGE_STRING1 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0
+#define HUGE_STRING2 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1
+#define HUGE_STRING3 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2
+#define HUGE_STRING4 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3
+ switch (D) {
+ case DiffType::Control:
+ return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
+ case DiffType::ChangeFirst:
+ return "-123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
+ case DiffType::ChangeMiddle:
+ return "0123456789" HUGE_STRING4 "01234-6789" HUGE_STRING4 "0123456789";
+ case DiffType::ChangeLast:
+ return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "012345678-";
+ }
+}
+
+TEST_ALWAYS_INLINE std::string makeString(Length L,
+ DiffType D = DiffType::Control,
+ Opacity O = Opacity::Transparent) {
+ switch (L) {
+ case Length::Empty:
+ return maybeOpaque("", O == Opacity::Opaque);
+ case Length::Small:
+ return maybeOpaque(getSmallString(D), O == Opacity::Opaque);
+ case Length::Large:
+ return maybeOpaque(getLargeString(D), O == Opacity::Opaque);
+ case Length::Huge:
+ return maybeOpaque(getHugeString(D), O == Opacity::Opaque);
+ }
+}
+
+template <class Length, class Opaque>
+struct StringConstructDestroyCStr {
+ static void run(benchmark::State& state) {
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(
+ makeString(Length(), DiffType::Control, Opaque()));
+ }
+ }
+
+ static std::string name() {
+ return "BM_StringConstructDestroyCStr" + Length::name() + Opaque::name();
+ }
+};
+
+template <class Length, bool MeasureCopy, bool MeasureDestroy>
+static void StringCopyAndDestroy(benchmark::State& state) {
+ static constexpr size_t NumStrings = 1024;
+ auto Orig = makeString(Length());
+ std::aligned_storage<sizeof(std::string)>::type Storage[NumStrings];
+
+ while (state.KeepRunningBatch(NumStrings)) {
+ if (!MeasureCopy)
+ state.PauseTiming();
+ for (size_t I = 0; I < NumStrings; ++I) {
+ ::new (static_cast<void*>(Storage + I)) std::string(Orig);
+ }
+ if (!MeasureCopy)
+ state.ResumeTiming();
+ if (!MeasureDestroy)
+ state.PauseTiming();
+ for (size_t I = 0; I < NumStrings; ++I) {
+ using S = std::string;
+ reinterpret_cast<S*>(Storage + I)->~S();
+ }
+ if (!MeasureDestroy)
+ state.ResumeTiming();
+ }
+}
+
+template <class Length>
+struct StringCopy {
+ static void run(benchmark::State& state) {
+ StringCopyAndDestroy<Length, true, false>(state);
+ }
+
+ static std::string name() { return "BM_StringCopy" + Length::name(); }
+};
+
+template <class Length>
+struct StringDestroy {
+ static void run(benchmark::State& state) {
+ StringCopyAndDestroy<Length, false, true>(state);
+ }
+
+ static std::string name() { return "BM_StringDestroy" + Length::name(); }
+};
+
+template <class Length>
+struct StringMove {
+ static void run(benchmark::State& state) {
+ // Keep two object locations and move construct back and forth.
+ std::aligned_storage<sizeof(std::string), alignof(std::string)>::type Storage[2];
+ using S = std::string;
+ size_t I = 0;
+ S *newS = new (static_cast<void*>(Storage)) std::string(makeString(Length()));
+ for (auto _ : state) {
+ // Switch locations.
+ I ^= 1;
+ benchmark::DoNotOptimize(Storage);
+ // Move construct into the new location,
+ S *tmpS = new (static_cast<void*>(Storage + I)) S(std::move(*newS));
+ // then destroy the old one.
+ newS->~S();
+ newS = tmpS;
+ }
+ newS->~S();
+ }
+
+ static std::string name() { return "BM_StringMove" + Length::name(); }
+};
+
+enum class Relation { Eq, Less, Compare };
+struct AllRelations : EnumValuesAsTuple<AllRelations, Relation, 3> {
+ static constexpr const char* Names[] = {"Eq", "Less", "Compare"};
+};
+
+template <class Rel, class LHLength, class RHLength, class DiffType>
+struct StringRelational {
+ static void run(benchmark::State& state) {
+ auto Lhs = makeString(RHLength());
+ auto Rhs = makeString(LHLength(), DiffType());
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(Lhs);
+ benchmark::DoNotOptimize(Rhs);
+ switch (Rel()) {
+ case Relation::Eq:
+ benchmark::DoNotOptimize(Lhs == Rhs);
+ break;
+ case Relation::Less:
+ benchmark::DoNotOptimize(Lhs < Rhs);
+ break;
+ case Relation::Compare:
+ benchmark::DoNotOptimize(Lhs.compare(Rhs));
+ break;
+ }
+ }
+ }
+
+ static bool skip() {
+ // Eq is commutative, so skip half the matrix.
+ if (Rel() == Relation::Eq && LHLength() > RHLength())
+ return true;
+ // We only care about control when the lengths differ.
+ if (LHLength() != RHLength() && DiffType() != ::DiffType::Control)
+ return true;
+ // For empty, only control matters.
+ if (LHLength() == Length::Empty && DiffType() != ::DiffType::Control)
+ return true;
+ return false;
+ }
+
+ static std::string name() {
+ return "BM_StringRelational" + Rel::name() + LHLength::name() +
+ RHLength::name() + DiffType::name();
+ }
+};
+
+enum class Depth { Shallow, Deep };
+struct AllDepths : EnumValuesAsTuple<AllDepths, Depth, 2> {
+ static constexpr const char* Names[] = {"Shallow", "Deep"};
+};
+
+enum class Temperature { Hot, Cold };
+struct AllTemperatures : EnumValuesAsTuple<AllTemperatures, Temperature, 2> {
+ static constexpr const char* Names[] = {"Hot", "Cold"};
+};
+
+template <class Temperature, class Depth, class Length>
+struct StringRead {
+ void run(benchmark::State& state) const {
+ static constexpr size_t NumStrings =
+ Temperature() == ::Temperature::Hot
+ ? 1 << 10
+ : /* Enough strings to overflow the cache */ 1 << 20;
+ static_assert((NumStrings & (NumStrings - 1)) == 0,
+ "NumStrings should be a power of two to reduce overhead.");
+
+ std::vector<std::string> Values(NumStrings, makeString(Length()));
+ size_t I = 0;
+ for (auto _ : state) {
+ // Jump long enough to defeat cache locality, and use a value that is
+ // coprime with NumStrings to ensure we visit every element.
+ I = (I + 17) % NumStrings;
+ const auto& V = Values[I];
+
+ // Read everything first. Escaping data() through DoNotOptimize might
+ // cause the compiler to have to recalculate information about `V` due to
+ // aliasing.
+ const char* const Data = V.data();
+ const size_t Size = V.size();
+ benchmark::DoNotOptimize(Data);
+ benchmark::DoNotOptimize(Size);
+ if (Depth() == ::Depth::Deep) {
+ // Read into the payload. This mainly shows the benefit of SSO when the
+ // data is cold.
+ benchmark::DoNotOptimize(*Data);
+ }
+ }
+ }
+
+ static bool skip() {
+ // Huge does not give us anything that Large doesn't have. Skip it.
+ if (Length() == ::Length::Huge) {
+ return true;
+ }
+ return false;
+ }
+
+ std::string name() const {
+ return "BM_StringRead" + Temperature::name() + Depth::name() +
+ Length::name();
+ }
+};
+
+void sanityCheckGeneratedStrings() {
+ for (auto Lhs : {Length::Empty, Length::Small, Length::Large, Length::Huge}) {
+ const auto LhsString = makeString(Lhs);
+ for (auto Rhs :
+ {Length::Empty, Length::Small, Length::Large, Length::Huge}) {
+ if (Lhs > Rhs)
+ continue;
+ const auto RhsString = makeString(Rhs);
+
+ // The smaller one must be a prefix of the larger one.
+ if (RhsString.find(LhsString) != 0) {
+ fprintf(stderr, "Invalid autogenerated strings for sizes (%d,%d).\n",
+ static_cast<int>(Lhs), static_cast<int>(Rhs));
+ std::abort();
+ }
+ }
+ }
+ // Verify the autogenerated diffs
+ for (auto L : {Length::Small, Length::Large, Length::Huge}) {
+ const auto Control = makeString(L);
+ const auto Verify = [&](std::string Exp, size_t Pos) {
+ // Only change on the Pos char.
+ if (Control[Pos] != Exp[Pos]) {
+ Exp[Pos] = Control[Pos];
+ if (Control == Exp)
+ return;
+ }
+ fprintf(stderr, "Invalid autogenerated diff with size %d\n",
+ static_cast<int>(L));
+ std::abort();
+ };
+ Verify(makeString(L, DiffType::ChangeFirst), 0);
+ Verify(makeString(L, DiffType::ChangeMiddle), Control.size() / 2);
+ Verify(makeString(L, DiffType::ChangeLast), Control.size() - 1);
}
}
-BENCHMARK(BM_StringCtorCStr)->Arg(1)->Arg(8)->Range(16, MAX_STRING_LEN / 4);
-BENCHMARK_MAIN();
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+
+ sanityCheckGeneratedStrings();
+
+ makeCartesianProductBenchmark<StringConstructDestroyCStr, AllLengths,
+ AllOpacity>();
+ makeCartesianProductBenchmark<StringCopy, AllLengths>();
+ makeCartesianProductBenchmark<StringMove, AllLengths>();
+ makeCartesianProductBenchmark<StringDestroy, AllLengths>();
+ makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
+ AllLengths, AllDiffTypes>();
+ makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
+ AllLengths>();
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/stringstream.bench.cpp b/benchmarks/stringstream.bench.cpp
index 75a7a284e072..828ef4b405f4 100644
--- a/benchmarks/stringstream.bench.cpp
+++ b/benchmarks/stringstream.bench.cpp
@@ -1,7 +1,9 @@
#include "benchmark/benchmark.h"
+#include "test_macros.h"
#include <sstream>
-double __attribute__((noinline)) istream_numbers();
+
+TEST_NOINLINE double istream_numbers();
double istream_numbers() {
const char *a[] = {
diff --git a/benchmarks/unordered_set_operations.bench.cpp b/benchmarks/unordered_set_operations.bench.cpp
index ee0ea29b8d21..1fee6d362c41 100644
--- a/benchmarks/unordered_set_operations.bench.cpp
+++ b/benchmarks/unordered_set_operations.bench.cpp
@@ -9,25 +9,26 @@
#include "ContainerBenchmarks.hpp"
#include "GenerateInput.hpp"
+#include "test_macros.h"
using namespace ContainerBenchmarks;
constexpr std::size_t TestNumInputs = 1024;
template <class _Size>
-inline __attribute__((__always_inline__))
+inline TEST_ALWAYS_INLINE
_Size loadword(const void* __p) {
_Size __r;
std::memcpy(&__r, __p, sizeof(__r));
return __r;
}
-inline __attribute__((__always_inline__))
+inline TEST_ALWAYS_INLINE
std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) {
return (__val >> __shift) | (__val << (64 - __shift));
}
-inline __attribute__((__always_inline__))
+inline TEST_ALWAYS_INLINE
std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
const std::size_t __mul = 0x9ddfea08eb382d69ULL;
std::size_t __a = (__u ^ __v) * __mul;
@@ -40,7 +41,7 @@ std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
template <std::size_t _Len>
-inline __attribute__((__always_inline__))
+inline TEST_ALWAYS_INLINE
std::size_t hash_len_0_to_8(const char* __s) {
static_assert(_Len == 4 || _Len == 8, "");
const uint64_t __a = loadword<uint32_t>(__s);
@@ -50,7 +51,7 @@ std::size_t hash_len_0_to_8(const char* __s) {
struct UInt32Hash {
UInt32Hash() = default;
- inline __attribute__((__always_inline__))
+ inline TEST_ALWAYS_INLINE
std::size_t operator()(uint32_t data) const {
return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
}
@@ -58,7 +59,7 @@ struct UInt32Hash {
struct UInt64Hash {
UInt64Hash() = default;
- inline __attribute__((__always_inline__))
+ inline TEST_ALWAYS_INLINE
std::size_t operator()(uint64_t data) const {
return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
}
@@ -66,7 +67,7 @@ struct UInt64Hash {
struct UInt128Hash {
UInt128Hash() = default;
- inline __attribute__((__always_inline__))
+ inline TEST_ALWAYS_INLINE
std::size_t operator()(__uint128_t data) const {
const __uint128_t __mask = static_cast<std::size_t>(-1);
const std::size_t __a = (std::size_t)(data & __mask);
@@ -77,7 +78,7 @@ struct UInt128Hash {
struct UInt32Hash2 {
UInt32Hash2() = default;
- inline __attribute__((__always_inline__))
+ inline TEST_ALWAYS_INLINE
std::size_t operator()(uint32_t data) const {
const uint32_t __m = 0x5bd1e995;
const uint32_t __r = 24;
@@ -97,7 +98,7 @@ struct UInt32Hash2 {
struct UInt64Hash2 {
UInt64Hash2() = default;
- inline __attribute__((__always_inline__))
+ inline TEST_ALWAYS_INLINE
std::size_t operator()(uint64_t data) const {
return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
}
diff --git a/cmake/Modules/HandleCompilerRT.cmake b/cmake/Modules/HandleCompilerRT.cmake
index 2e0e69e5e085..1ce256574941 100644
--- a/cmake/Modules/HandleCompilerRT.cmake
+++ b/cmake/Modules/HandleCompilerRT.cmake
@@ -8,6 +8,9 @@ function(find_compiler_rt_library name dest)
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
diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake
index ef3b4f5dde22..1c19d7e01af7 100644
--- a/cmake/Modules/HandleLibCXXABI.cmake
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -41,7 +41,7 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
get_filename_component(ifile ${fpath} NAME)
set(src ${incpath}/${fpath})
- set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${fpath})
+ set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${ifile})
add_custom_command(OUTPUT ${dst}
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake
index 65f7d187f3bd..fb60318a330d 100644
--- a/cmake/Modules/HandleLibcxxFlags.cmake
+++ b/cmake/Modules/HandleLibcxxFlags.cmake
@@ -16,6 +16,7 @@ macro(mangle_name str output)
string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
string(REPLACE "-" "_" strippedStr "${strippedStr}")
+ string(REPLACE ":" "_COLON_" strippedStr "${strippedStr}")
string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
string(REPLACE "+" "X" strippedStr "${strippedStr}")
string(TOUPPER "${strippedStr}" ${output})
@@ -44,6 +45,29 @@ macro(check_flag_supported flag)
check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
endmacro()
+macro(append_flags DEST)
+ foreach(value ${ARGN})
+ list(APPEND ${DEST} ${value})
+ list(APPEND ${DEST} ${value})
+ endforeach()
+endmacro()
+
+# If the specified 'condition' is true then append the specified list of flags to DEST
+macro(append_flags_if condition DEST)
+ if (${condition})
+ list(APPEND ${DEST} ${ARGN})
+ endif()
+endmacro()
+
+# Add each flag in the list specified by DEST if that flag is supported by the current compiler.
+macro(append_flags_if_supported DEST)
+ foreach(flag ${ARGN})
+ mangle_name("${flag}" flagname)
+ check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+ append_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag})
+ endforeach()
+endmacro()
+
# Add a macro definition if condition is true.
macro(define_if condition def)
if (${condition})
diff --git a/docs/BuildingLibcxx.rst b/docs/BuildingLibcxx.rst
index d0b03c675c8b..a498c0027bd1 100644
--- a/docs/BuildingLibcxx.rst
+++ b/docs/BuildingLibcxx.rst
@@ -222,6 +222,15 @@ libc++ specific options
Define libc++ destination prefix.
+.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL
+
+ **Default**: ``OFF``
+
+ Do not export any symbols from the static libc++ library. This is useful when
+ This is useful when the static libc++ library is being linked into shared
+ libraries that may be used in with other shared libraries that use different
+ C++ library. We want to avoid avoid exporting any libc++ symbols in that case.
+
.. _libc++experimental options:
libc++experimental Specific Options
@@ -316,6 +325,15 @@ libc++ Feature Options
Build the libc++ benchmark tests and the Google Benchmark library needed
to support them.
+.. option:: LIBCXX_BENCHMARK_TEST_ARGS:STRING
+
+ **Default**: ``--benchmark_min_time=0.01``
+
+ A semicolon list of arguments to pass when running the libc++ benchmarks using the
+ ``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very short amount of time,
+ since the primary use of ``check-cxx-benchmarks`` is to get test and sanitizer coverage, not to
+ get accurate measurements.
+
.. option:: LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING
**Default**:: ``""``
@@ -332,6 +350,15 @@ libc++ Feature Options
Use the specified GCC toolchain and standard library when building the native
stdlib benchmark tests.
+.. option:: LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL
+
+ **Default**: ``OFF``
+
+ Pick the default for whether to constrain ABI-unstable symbols to
+ each individual translation unit. This setting controls whether
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined by default --
+ see the documentation of that macro for details.
+
libc++ ABI Feature Options
--------------------------
@@ -351,6 +378,20 @@ The following options allow building libc++ for a different ABI version.
Build the "unstable" ABI version of libc++. Includes all ABI changing features
on top of the current stable version.
+.. option:: LIBCXX_ABI_NAMESPACE:STRING
+
+ **Default**: ``__n`` where ``n`` is the current ABI version.
+
+ This option defines the name of the inline ABI versioning namespace. It can be used for building
+ custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
+ with other libc++ versions.
+
+ .. warning::
+ When providing a custom namespace, it's the users responsibility to ensure the name won't cause
+ conflicts with other names defined by libc++, both now and in the future. In particular, inline
+ namespaces of the form ``__[0-9]+`` are strictly reserved by libc++ and may not be used by users.
+ Doing otherwise could cause conflicts and hinder libc++ ABI evolution.
+
.. option:: LIBCXX_ABI_DEFINES:STRING
**Default**: ``""``
diff --git a/docs/DesignDocs/AvailabilityMarkup.rst b/docs/DesignDocs/AvailabilityMarkup.rst
index b8b44509790d..4e6d80b50bf8 100644
--- a/docs/DesignDocs/AvailabilityMarkup.rst
+++ b/docs/DesignDocs/AvailabilityMarkup.rst
@@ -24,11 +24,11 @@ systems. For example::
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
- #define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
+ # 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
+ # 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.
@@ -43,9 +43,9 @@ For example::
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 {
+ _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:
@@ -55,7 +55,7 @@ or on a particular symbol:
Testing
=======
-Some parameters can be passed to lit to run the test-suite and exercising the
+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
@@ -65,14 +65,11 @@ availability.
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/`.
-* The `with_availability` boolean parameter enables the availability markup.
Tests can be marked as XFAIL based on multiple features made available by lit:
-* if either `use_system_cxx_lib` or `with_availability` is passed to lit,
- assuming `--param=platform=macosx10.8` is passed as well the following
- features will be available:
+* if `--param=platform=macosx10.8` is passed, the following features will be available:
- availability
- availability=x86_64
@@ -81,11 +78,11 @@ Tests can be marked as XFAIL based on multiple features made available by lit:
- availability=x86_64-apple-macosx10.8
- availability=macosx10.8
- This feature is used to XFAIL a test that *is* using a class of a method marked
+ 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` is passed to lit, the following features will also
- be available:
+* 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
@@ -94,21 +91,9 @@ Tests can be marked as XFAIL based on multiple features made available by lit:
- 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 of a method
+ 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 we know that it exhibits a but in the libc on a
- particular system version.
-
-* if `with_availability` is passed to lit, the following features will also
- be available:
-
- - availability_markup
- - availability_markup=x86_64
- - availability_markup=macosx
- - availability_markup=x86_64-macosx
- - availability_markup=x86_64-apple-macosx10.8
- - availability_markup=macosx10.8
-
- This feature is used to XFAIL a test that *is* using a class of a method
- marked as unavailable *but* that is expected to *pass* if deployed on an older
- system. For example if it is using a symbol in a statically evaluated context.
+ 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 88102251d932..29156bff8bc9 100644
--- a/docs/DesignDocs/CapturingConfigInfo.rst
+++ b/docs/DesignDocs/CapturingConfigInfo.rst
@@ -28,7 +28,7 @@ Design Goals
It makes developers lives harder if they have to regenerate the libc++ headers
every time they are modified.
-* The solution should not make any of the libc++ headers dependant on
+* The solution should not make any of the libc++ headers dependent on
files generated by the build system. The headers should be able to compile
out of the box without any modification.
diff --git a/docs/DesignDocs/FeatureTestMacros.rst b/docs/DesignDocs/FeatureTestMacros.rst
new file mode 100644
index 000000000000..d55af96c6749
--- /dev/null
+++ b/docs/DesignDocs/FeatureTestMacros.rst
@@ -0,0 +1,44 @@
+===================
+Feature Test Macros
+===================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+Libc++ implements the C++ feature test macros as specified in the C++2a standard,
+and before that in non-normative guiding documents (`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`)
+
+Design
+======
+
+Feature test macros are tricky to track, implement, test, and document correctly.
+They must be available from a list of headers, they may have different values in
+different dialects, and they may or may not be implemented by libc++. In order to
+track all of these conditions correctly and easily, we want a Single Source of
+Truth (SSoT) that defines each feature test macro, its values, the headers it
+lives in, and whether or not is is implemented by libc++. From this SSoA we
+have enough information to automatically generate the `<version>` header,
+the tests, and the documentation.
+
+Therefore we maintain a SSoA in
+`libcxx/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py`
+which doubles as a script to generate the following components:
+
+* The `<version>` header.
+* The version tests under `support.limits.general`.
+* Documentation of libc++'s implementation of each macro.
+
+Usage
+=====
+
+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 `<version>` header as a
+temporary file. The generated `<version>` header should be merged with the
+existing one. \ No newline at end of file
diff --git a/docs/DesignDocs/VisibilityMacros.rst b/docs/DesignDocs/VisibilityMacros.rst
index 878566ea0bc1..d0d4f0adb220 100644
--- a/docs/DesignDocs/VisibilityMacros.rst
+++ b/docs/DesignDocs/VisibilityMacros.rst
@@ -22,11 +22,11 @@ Visibility Macros
Mark a symbol as being exported by the libc++ library. This attribute must
be applied to the declaration of all functions exported by the libc++ dylib.
-**_LIBCPP_EXTERN_VIS**
+**_LIBCPP_EXPORTED_FROM_ABI**
Mark a symbol as being exported by the libc++ library. This attribute may
- only be applied to objects defined in the libc++ library. On Windows this
- macro applies `dllimport`/`dllexport` to the symbol. On all other platforms
- this macro has no effect.
+ only be applied to objects defined in the libc++ runtime library. On Windows,
+ this macro applies `dllimport`/`dllexport` to the symbol, and on other
+ platforms it gives the symbol default visibility.
**_LIBCPP_OVERRIDABLE_FUNC_VIS**
Mark a symbol as being exported by the libc++ library, but allow it to be
@@ -42,9 +42,57 @@ Visibility Macros
**_LIBCPP_HIDE_FROM_ABI**
Mark a function as not being part of the ABI of any final linked image that
- uses it, and also as being internal to each TU that uses that function. In
- other words, the address of a function marked with this attribute is not
- guaranteed to be the same across translation units.
+ uses it.
+
+**_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
+ maintain ABI compatibility for symbols that have been historically exported
+ by libc++ in v1 of the ABI, but that we don't want to export in the future.
+
+ This macro works as follows. When we build libc++, we either hide the symbol
+ from the ABI (if the symbol is not part of the ABI in the version we're
+ building), or we leave it included. From user code (i.e. when we're not
+ building libc++), the macro always marks symbols as internal so that programs
+ built using new libc++ headers stop relying on symbols that are removed from
+ the ABI in a future version. Each time we release a new stable version of the
+ ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can
+ use it to start removing symbols from the ABI after that stable version.
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU**
+ This macro controls whether symbols hidden from the ABI with `_LIBCPP_HIDE_FROM_ABI`
+ are local to each translation unit in addition to being local to each final
+ linked image. This macro is defined to either 0 or 1. When it is defined to
+ 1, translation units compiled with different versions of libc++ can be linked
+ together, since all non ABI-facing functions are local to each translation unit.
+ This allows static archives built with different versions of libc++ to be linked
+ together. This also means that functions marked with `_LIBCPP_HIDE_FROM_ABI`
+ are not guaranteed to have the same address across translation unit boundaries.
+
+ When the macro is defined to 0, there is no guarantee that translation units
+ compiled with different versions of libc++ can interoperate. However, this
+ leads to code size improvements, since non ABI-facing functions can be
+ deduplicated across translation unit boundaries.
+
+ This macro can be defined by users to control the behavior they want from
+ libc++. The default value of this macro (0 or 1) is controlled by whether
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined, which is intended to
+ be used by vendors only (see below).
+
+**_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT**
+ This macro controls the default value for `_LIBCPP_HIDE_FROM_ABI_PER_TU`.
+ When the macro is defined, per TU ABI insulation is enabled by default, and
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 1 unless overridden by users.
+ Otherwise, per TU ABI insulation is disabled by default, and
+ `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 0 unless overridden by users.
+
+ This macro is intended for vendors to control whether they want to ship
+ libc++ with per TU ABI insulation enabled by default. Users can always
+ control the behavior they want by defining `_LIBCPP_HIDE_FROM_ABI_PER_TU`
+ appropriately.
+
+ By default, this macro is not defined, which means that per TU ABI insulation
+ is not provided unless explicitly overridden by users.
**_LIBCPP_TYPE_VIS**
Mark a type's typeinfo, vtable and members as having default visibility.
@@ -139,15 +187,6 @@ Visibility Macros
against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
`_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
-**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY**
- Mark a member function of a class template as visible and always inline. This
- macro should only be applied to member functions of class templates that are
- externally instantiated. It is important that these symbols are not marked
- as hidden as that will prevent the dylib definition from being found.
-
- This macro is used to maintain ABI compatibility for symbols that have been
- historically exported by the libc++ library but are now marked inline.
-
**_LIBCPP_EXCEPTION_ABI**
Mark the member functions, typeinfo, and vtable of the type as being exported
by the libc++ library. This macro must be applied to all *exception types*.
diff --git a/docs/FeatureTestMacroTable.rst b/docs/FeatureTestMacroTable.rst
new file mode 100644
index 000000000000..d900497eba70
--- /dev/null
+++ b/docs/FeatureTestMacroTable.rst
@@ -0,0 +1,200 @@
+.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+This file documents the feature test macros currently supported by libc++.
+
+.. _feature-status:
+
+Status
+======
+
+.. table:: Current Status
+ :name: feature-status-table
+ :widths: auto
+
+ ================================================= =================
+ Macro Name Value
+ ================================================= =================
+ **C++ 14**
+ -------------------------------------------------------------------
+ ``__cpp_lib_chrono_udls`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_complex_udls`` ``201309L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_exchange_function`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_generic_associative_lookup`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_integer_sequence`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_integral_constant_callable`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_final`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_null_pointer`` ``201309L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_reverse_iterator`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_unique`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_null_iterators`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_quoted_string_io`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_result_of_sfinae`` ``201210L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_timed_mutex`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_string_udls`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transformation_trait_aliases`` ``201304L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transparent_operators`` ``201210L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_tuple_element_t`` ``201402L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_tuples_by_type`` ``201304L``
+ ------------------------------------------------- -----------------
+ **C++ 17**
+ -------------------------------------------------------------------
+ ``__cpp_lib_addressof_constexpr`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_allocator_traits_is_always_equal`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_any`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_apply`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_array_constexpr`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_as_const`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_atomic_is_always_lock_free`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bool_constant`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_boyer_moore_searcher`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_byte`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_chrono`` ``201611L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_clamp`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_enable_shared_from_this`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_execution`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_filesystem`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_gcd_lcm`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_hardware_interference_size`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_has_unique_object_representations`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_hypot`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_incomplete_container_elements`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_invoke`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_aggregate`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_invocable`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_swappable`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_launder`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_logical_traits`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_make_from_tuple`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_map_try_emplace`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_math_special_functions`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_memory_resource`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_node_extract`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_nonmember_container_access`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_not_fn`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_optional`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_parallel_algorithm`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_raw_memory_algorithms`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_sample`` ``201603L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_scoped_lock`` ``201703L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_mutex`` ``201505L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_ptr_arrays`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_shared_ptr_weak_type`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_string_view`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_to_chars`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_transparent_operators`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_type_trait_variable_templates`` ``201510L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_uncaught_exceptions`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_unordered_map_try_emplace`` ``201411L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_variant`` ``201606L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_void_t`` ``201411L``
+ ------------------------------------------------- -----------------
+ **C++ 2a**
+ -------------------------------------------------------------------
+ ``__cpp_lib_atomic_ref`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bind_front`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_bit_cast`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_char8_t`` ``201811L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_concepts`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_misc`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_swap_algorithms`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_destroying_delete`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_erase_if`` ``201811L``
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_generic_unordered_lookup`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_is_constant_evaluated`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_list_remove_return_type`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_ranges`` *unimplemented*
+ ------------------------------------------------- -----------------
+ ``__cpp_lib_three_way_comparison`` *unimplemented*
+ ================================================= =================
+
+
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
new file mode 100644
index 000000000000..20be9f627ef8
--- /dev/null
+++ b/docs/ReleaseNotes.rst
@@ -0,0 +1,62 @@
+========================================
+Libc++ 8.0.0 (In-Progress) Release Notes
+========================================
+
+.. contents::
+ :local:
+ :depth: 2
+
+Written by the `Libc++ Team <https://libcxx.llvm.org>`_
+
+.. warning::
+
+ These are in-progress notes for the upcoming libc++ 8 release.
+ Release notes for previous releases can be found on
+ `the Download Page <https://releases.llvm.org/download.html>`_.
+
+Introduction
+============
+
+This document contains the release notes for the libc++ C++ Standard Library,
+part of the LLVM Compiler Infrastructure, release 8.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 <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
+be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.
+
+For more information about libc++, please see the `Libc++ Web Site
+<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
+
+Note that if you are reading this file from a Subversion 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 <https://llvm.org/releases/>`_.
+
+What's New in Libc++ 8.0.0?
+===========================
+
+New Features
+------------
+
+API Changes
+-----------
+- Building libc++ for Mac OSX 10.6 is not supported anymore.
+- Starting with LLVM 8.0.0, users that wish to link together translation units
+ built with different versions of libc++'s headers into the same final linked
+ image MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building
+ those translation units. Not defining _LIBCPP_HIDE_FROM_ABI_PER_TU to 1 and
+ linking translation units built with different versions of libc++'s headers
+ together may lead to ODR violations and ABI issues. On the flipside, code
+ size improvements should be expected for everyone not defining the macro.
+- Starting with LLVM 8.0.0, std::dynarray has been removed from the library.
+ std::dynarray was a feature proposed for C++14 that was pulled from the
+ Standard at the last minute and was never standardized. Since there are no
+ plans to standardize this facility it is being removed.
+- Starting with LLVM 8.0.0, std::bad_array_length has been removed from the
+ library. std::bad_array_length was a feature proposed for C++14 alongside
+ std::dynarray, but it never actually made it into the C++ Standard. There
+ are no plans to standardize this feature at this time. Formally speaking,
+ this removal constitutes an ABI break because the symbols were shipped in
+ the shared library. However, on macOS systems, the feature was not usable
+ because it was hidden behind availability annotations. We do not expect
+ any actual breakage to happen from this change.
diff --git a/docs/TestingLibcxx.rst b/docs/TestingLibcxx.rst
index 43c0684dc7de..ebbbf628ac04 100644
--- a/docs/TestingLibcxx.rst
+++ b/docs/TestingLibcxx.rst
@@ -138,8 +138,7 @@ configuration. Passing the option on the command line will override the default.
Specify the directory of the libc++ library to use at runtime. This directory
is not added to the linkers search path. This can be used to compile tests
against one version of libc++ and run them using another. The default value
- for this option is `cxx_library_root`. This option cannot be used
- when use_system_cxx_lib is provided.
+ for this option is `cxx_library_root`.
.. option:: use_system_cxx_lib=<bool>
@@ -155,14 +154,6 @@ configuration. Passing the option on the command line will override the default.
the default value. Otherwise the default value is True on Windows and False
on every other platform.
-.. option:: no_default_flags=<bool>
-
- **Default**: False
-
- Disable all default compile and link flags from being added. When this
- option is used only flags specified using the compile_flags and link_flags
- will be used.
-
.. option:: compile_flags="<list-of-args>"
Specify additional compile flags as a space delimited string.
diff --git a/docs/UsingLibcxx.rst b/docs/UsingLibcxx.rst
index e10a27c598a1..899656cca1d5 100644
--- a/docs/UsingLibcxx.rst
+++ b/docs/UsingLibcxx.rst
@@ -203,8 +203,10 @@ thread safety annotations.
This macro disables the additional diagnostics generated by libc++ using the
`diagnose_if` attribute. These additional diagnostics include checks for:
- * Giving `set`, `map`, `multiset`, `multimap` a comparator which is not
- const callable.
+ * Giving `set`, `map`, `multiset`, `multimap` and their `unordered_`
+ counterparts a comparator which is not const callable.
+ * Giving an unordered associative container a hasher that is not const
+ callable.
**_LIBCPP_NO_VCRUNTIME**:
Microsoft's C and C++ headers are fairly entangled, and some of their C++
@@ -226,6 +228,26 @@ thread safety annotations.
replacement scenarios from working, e.g. replacing `operator new` and
expecting a non-replaced `operator new[]` to call the replaced `operator new`.
+**_LIBCPP_ENABLE_NODISCARD**:
+ Allow the library to add ``[[nodiscard]]`` attributes to entities not specified
+ as ``[[nodiscard]]`` by the current language dialect. This includes
+ backporting applications of ``[[nodiscard]]`` from newer dialects and
+ additional extended applications at the discretion of the library. All
+ additional applications of ``[[nodiscard]]`` are disabled by default.
+ See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>` for
+ more information.
+
+**_LIBCPP_DISABLE_NODISCARD_EXT**:
+ This macro prevents the library from applying ``[[nodiscard]]`` to entities
+ purely as an extension. See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
+ for more information.
+
+**_LIBCPP_ENABLE_DEPRECATION_WARNINGS**:
+ This macro enables warnings when using deprecated components. For example,
+ when compiling in C++11 mode, using `std::auto_ptr` with the macro defined
+ will trigger a warning saying that `std::auto_ptr` is deprecated. By default,
+ this macro is not defined.
+
C++17 Specific Configuration Macros
-----------------------------------
**_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
@@ -238,3 +260,58 @@ C++17 Specific Configuration Macros
**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
This macro is used to re-enable `std::auto_ptr` in C++17.
+
+C++2a 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]] <nodiscard extension>`
+ for more information.
+
+
+Libc++ Extensions
+=================
+
+This section documents various extensions provided by libc++, how they're
+provided, and any information regarding how to use them.
+
+.. _nodiscard extension:
+
+Extended applications of ``[[nodiscard]]``
+------------------------------------------
+
+The ``[[nodiscard]]`` attribute is intended to help users find bugs where
+function return values are ignored when they shouldn't be. After C++17 the
+C++ standard has started to declared such library functions as ``[[nodiscard]]``.
+However, this application is limited and applies only to dialects after C++17.
+Users who want help diagnosing misuses of STL functions may desire a more
+liberal application of ``[[nodiscard]]``.
+
+For this reason libc++ provides an extension that does just that! The
+extension must be enabled by defining ``_LIBCPP_ENABLE_NODISCARD``. The extended
+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,
+ 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``.
+
+Applications of the second form, which are pure extensions, may be disabled
+by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``.
+
+
+Entities declared with ``_LIBCPP_NODISCARD_EXT``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section lists all extended applications of ``[[nodiscard]]`` to entities
+which no dialect declares as such (See the second form described above).
+
+* ``get_temporary_buffer``
diff --git a/docs/conf.py b/docs/conf.py
index 4c1ea3653cdb..50b372cf84e2 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -40,16 +40,16 @@ master_doc = 'index'
# General information about the project.
project = u'libc++'
-copyright = u'2011-2017, LLVM Project'
+copyright = u'2011-2018, LLVM Project'
# 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 = '7.0'
+version = '8.0'
# The full version, including alpha/beta/rc tags.
-release = '7.0'
+release = '8.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -241,7 +241,7 @@ texinfo_documents = [
#texinfo_show_urls = 'footnote'
-# FIXME: Define intersphinx configration.
+# FIXME: Define intersphinx configuration.
intersphinx_mapping = {}
diff --git a/docs/index.rst b/docs/index.rst
index e4b3a879da94..fddf74b66a98 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -34,11 +34,17 @@ Getting Started with libc++
.. toctree::
:maxdepth: 2
+ ReleaseNotes
UsingLibcxx
BuildingLibcxx
TestingLibcxx
+.. toctree::
+ :hidden:
+
+ FeatureTestMacroTable
+
Current Status
--------------
@@ -79,8 +85,8 @@ reasons, but some of the major ones are:
Platform and Compiler Support
-----------------------------
-libc++ is known to work on the following platforms, using gcc-4.2 and
-clang (lack of C++11 language support disables some functionality).
+libc++ is known to work on the following platforms, using gcc and
+clang.
Note that functionality provided by ``<atomic>`` is only functional with clang
and GCC.
@@ -104,8 +110,9 @@ C++ Dialect Support
* C++11 - Complete
* `C++14 - Complete <http://libcxx.llvm.org/cxx1y_status.html>`__
-* `C++1z - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
+* `C++17 - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
* `Post C++14 Technical Specifications - In Progress <http://libcxx.llvm.org/ts1z_status.html>`__
+* :ref:`C++ Feature Test Macro Status <feature-status>`
Notes and Known Issues
----------------------
@@ -135,6 +142,7 @@ Design Documents
DesignDocs/VisibilityMacros
DesignDocs/ThreadingSupportAPI
DesignDocs/FileTimeType
+ DesignDocs/FeatureTestMacros
* `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
* `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
@@ -160,21 +168,18 @@ and `Getting started with LLVM <http://llvm.org/docs/GettingStarted.html>`__.
If you think you've found a bug in libc++, please report it using
the `LLVM Bugzilla`_. If you're not sure, you
-can post a message to the `cfe-dev mailing list`_ or on IRC.
-Please include "libc++" in your subject.
+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 <http://llvm.org/docs/Phabricator.html>`_. Please include [libcxx] in the subject and
-add `cfe-commits` as a subscriber. Also make sure you are subscribed to the
-`cfe-commits mailing list <http://lists.llvm.org/mailman/listinfo/cfe-commits>`_.
+`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please add `libcxx-commits` as a subscriber.
+Also make sure you are subscribed to the `libcxx-commits mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-commits>`_.
**Discussion and Questions**
Send discussions and questions to the
-`cfe-dev mailing list <http://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
-Please include [libcxx] in the subject.
+`libcxx-dev mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-dev>`_.
@@ -183,7 +188,7 @@ Quick Links
* `LLVM Homepage <http://llvm.org/>`_
* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
* `LLVM Bugzilla <https://bugs.llvm.org/>`_
-* `cfe-commits Mailing List`_
-* `cfe-dev Mailing List`_
+* `libcxx-commits Mailing List`_
+* `libcxx-dev Mailing List`_
* `Browse libc++ -- SVN <http://llvm.org/svn/llvm-project/libcxx/trunk/>`_
* `Browse libc++ -- ViewVC <http://llvm.org/viewvc/llvm-project/libcxx/trunk/>`_
diff --git a/fuzzing/fuzzing.cpp b/fuzzing/fuzzing.cpp
index 8888cbeac72e..ad377bcac467 100644
--- a/fuzzing/fuzzing.cpp
+++ b/fuzzing/fuzzing.cpp
@@ -8,18 +8,18 @@
//
//===----------------------------------------------------------------------===//
-// A set of routines to use when fuzzing the algorithms in libc++
-// Each one tests a single algorithm.
+// 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 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.
+// 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.
+// 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.
@@ -32,574 +32,587 @@
#include <iostream>
-// If we had C++14, we could use the four iterator version of is_permutation and equal
+// 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.
+// 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) {}
- };
+ 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);
+ 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;
- }
+ 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;
- }
+ 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) 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;
+{
+ return lhs.key == rhs.key && lhs.payload == rhs.payload;
}
template<typename T>
struct is_even
{
- bool operator () (const T &t) const
- {
- return t % 2 == 0;
- }
+ bool operator () (const T &t) const
+ {
+ return t % 2 == 0;
+ }
};
template<>
struct is_even<stable_test>
{
- bool operator () (const stable_test &t) const
- {
- return t.key % 2 == 0;
- }
+ bool operator () (const stable_test &t) const
+ {
+ return t.key % 2 == 0;
+ }
};
typedef std::vector<uint8_t> Vec;
typedef std::vector<stable_test> 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
+// 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;
+ 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 <typename Iter1, typename Iter2>
bool is_permutation(Iter1 first1, Iter1 last1, Iter2 first2)
{
- static_assert((std::is_same<typename std::iterator_traits<Iter1>::value_type, uint8_t>::value), "");
- static_assert((std::is_same<typename std::iterator_traits<Iter2>::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;
+ static_assert((std::is_same<typename std::iterator_traits<Iter1>::value_type, uint8_t>::value), "");
+ static_assert((std::is_same<typename std::iterator_traits<Iter2>::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 ==
+// == sort ==
int sort(const uint8_t *data, size_t size)
{
- Vec working(data, data + size);
- std::sort(working.begin(), working.end());
+ 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;
+ 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 ==
+// == 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;
+ 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 ==
+// == 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<uint8_t>());
+ Vec working(data, data + size);
+ auto iter = std::partition(working.begin(), working.end(), is_even<uint8_t>());
- if (!std::all_of (working.begin(), iter, is_even<uint8_t>())) return 1;
- if (!std::none_of(iter, working.end(), is_even<uint8_t>())) return 2;
- if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
- return 0;
+ if (!std::all_of (working.begin(), iter, is_even<uint8_t>())) return 1;
+ if (!std::none_of(iter, working.end(), is_even<uint8_t>())) return 2;
+ if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
+ return 0;
}
-// == partition_copy ==
+// == 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<Vec>(v1), std::back_inserter<Vec>(v2),
- is_even<uint8_t>());
-
-// 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<uint8_t>())) return 2;
- if (!std::none_of(v2.begin(), v2.end(), is_even<uint8_t>())) return 3;
-
-// Every value in both vectors has to be in the original
- 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;
+ Vec v1, v2;
+ auto iter = std::partition_copy(data, data + size,
+ std::back_inserter<Vec>(v1), std::back_inserter<Vec>(v2),
+ is_even<uint8_t>());
+
+// 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<uint8_t>())) return 2;
+ if (!std::none_of(v2.begin(), v2.end(), is_even<uint8_t>())) 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 ==
+// == 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<stable_test>());
-
- if (!std::all_of (working.begin(), iter, is_even<stable_test>())) return 1;
- if (!std::none_of(iter, working.end(), is_even<stable_test>())) 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;
+ 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<stable_test>());
+
+ if (!std::all_of (working.begin(), iter, is_even<stable_test>())) return 1;
+ if (!std::none_of(iter, working.end(), is_even<stable_test>())) 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
+// == 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;
+ 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
+// == 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;
+ 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
+// == 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;
+ 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"
+// The second sequence has been "uniqued"
template <typename Iter1, typename Iter2>
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;
+ 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 ==
+// == 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;
+ 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 ==
+// == 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<Vec>(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;
+ Vec working(data, data + size);
+ std::sort(working.begin(), working.end());
+ Vec results;
+ (void) std::unique_copy(working.begin(), working.end(),
+ std::back_inserter<Vec>(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
+// -- 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;
+ 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;
+ (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;
+ (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;
+ (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;
+ (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;
+ (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;
+ (void) regex_helper(data, size, std::regex_constants::egrep);
+ return 0;
}
-// -- heap fuzzers
+// -- heap fuzzers
int make_heap (const uint8_t *data, size_t size)
{
- Vec working(data, data + size);
- std::make_heap(working.begin(), working.end());
+ 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;
+ 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;
+ 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;
+// 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;
- }
+// 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;
+ 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());
+ 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;
- }
+// 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;
+ return 0;
}
-// -- search fuzzers
+// -- 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<uint8_t>::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;
+ if (size < 2) return 0;
+
+ const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::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 <typename S>
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<uint8_t>::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;
+ if (size < 2) return 0;
+
+ const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::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
+// These are still in std::experimental
// int search_boyer_moore (const uint8_t *data, size_t size)
// {
-// return search_helper<std::boyer_moore_searcher<const uint8_t *>>(data, size);
+// return search_helper<std::boyer_moore_searcher<const uint8_t *>>(data, size);
// }
-//
+//
// int search_boyer_moore_horspool (const uint8_t *data, size_t size)
// {
-// return search_helper<std::boyer_moore_horspool_searcher<const uint8_t *>>(data, size);
+// return search_helper<std::boyer_moore_horspool_searcher<const uint8_t *>>(data, size);
// }
-// -- set operation fuzzers
+// -- set operation fuzzers
template <typename S>
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<uint8_t>::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());
+ assert(size > 1);
+
+ const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::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/include/CMakeLists.txt b/include/CMakeLists.txt
index d9def18d725c..73f7cfc4d8e3 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -25,6 +25,7 @@ set(files
any
array
atomic
+ bit
bitset
cassert
ccomplex
@@ -68,7 +69,6 @@ set(files
experimental/chrono
experimental/coroutine
experimental/deque
- experimental/dynarray
experimental/filesystem
experimental/forward_list
experimental/functional
diff --git a/include/__bit_reference b/include/__bit_reference
index 3e4a21d261ff..c208af2b4d76 100644
--- a/include/__bit_reference
+++ b/include/__bit_reference
@@ -12,6 +12,7 @@
#define _LIBCPP___BIT_REFERENCE
#include <__config>
+#include <bit>
#include <algorithm>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -254,18 +255,18 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
__storage_type __dn = _VSTD::min(__clz_f, __n);
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
- __r = _VSTD::__pop_count(*__first.__seg_ & __m);
+ __r = _VSTD::__popcount(*__first.__seg_ & __m);
__n -= __dn;
++__first.__seg_;
}
// do middle whole words
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
- __r += _VSTD::__pop_count(*__first.__seg_);
+ __r += _VSTD::__popcount(*__first.__seg_);
// do last partial word
if (__n > 0)
{
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- __r += _VSTD::__pop_count(*__first.__seg_ & __m);
+ __r += _VSTD::__popcount(*__first.__seg_ & __m);
}
return __r;
}
@@ -285,18 +286,18 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
__storage_type __dn = _VSTD::min(__clz_f, __n);
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
- __r = _VSTD::__pop_count(~*__first.__seg_ & __m);
+ __r = _VSTD::__popcount(~*__first.__seg_ & __m);
__n -= __dn;
++__first.__seg_;
}
// do middle whole words
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
- __r += _VSTD::__pop_count(~*__first.__seg_);
+ __r += _VSTD::__popcount(~*__first.__seg_);
// do last partial word
if (__n > 0)
{
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- __r += _VSTD::__pop_count(~*__first.__seg_ & __m);
+ __r += _VSTD::__popcount(~*__first.__seg_ & __m);
}
return __r;
}
diff --git a/include/__config b/include/__config
index 639d06c9f5d7..f0bc3483facd 100644
--- a/include/__config
+++ b/include/__config
@@ -33,14 +33,10 @@
# define _GNUC_VER_NEW 0
#endif
-#define _LIBCPP_VERSION 7000
+#define _LIBCPP_VERSION 8000
#ifndef _LIBCPP_ABI_VERSION
-# ifdef __Fuchsia__
-# define _LIBCPP_ABI_VERSION 2
-# else
-# define _LIBCPP_ABI_VERSION 1
-# endif
+# define _LIBCPP_ABI_VERSION 1
#endif
#ifndef _LIBCPP_STD_VER
@@ -99,6 +95,8 @@
// Use the smallest possible integer type to represent the index of the variant.
// Previously libc++ used "unsigned int" exclusivly.
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+// Unstable attempt to provide a more optimized std::function
+# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
#elif _LIBCPP_ABI_VERSION == 1
# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support
@@ -123,7 +121,9 @@
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
-#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
+#ifndef _LIBCPP_ABI_NAMESPACE
+# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
+#endif
#if __cplusplus < 201103L
#define _LIBCPP_CXX03_LANG
@@ -328,6 +328,43 @@
# define _LIBCPP_NO_CFI
#endif
+#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
+# if defined(__FreeBSD__)
+# define _LIBCPP_HAS_QUICK_EXIT
+# define _LIBCPP_HAS_C11_FEATURES
+# elif defined(__Fuchsia__)
+# define _LIBCPP_HAS_QUICK_EXIT
+# define _LIBCPP_HAS_TIMESPEC_GET
+# define _LIBCPP_HAS_C11_FEATURES
+# 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_TIMESPEC_GET
+# endif
+# else // defined(_LIBCPP_HAS_MUSL_LIBC)
+# define _LIBCPP_HAS_QUICK_EXIT
+# define _LIBCPP_HAS_TIMESPEC_GET
+# define _LIBCPP_HAS_C11_FEATURES
+# endif
+# endif // __linux__
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+#elif defined(_LIBCPP_COMPILER_CLANG)
+# 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)
+#endif
+
+#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
+
#if defined(_LIBCPP_COMPILER_CLANG)
// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
@@ -342,7 +379,7 @@
# define _ALIGNAS_TYPE(x) alignas(x)
# define _ALIGNAS(x) alignas(x)
#else
-# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
#endif
@@ -430,28 +467,6 @@ typedef __char32_t char32_t;
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
#endif
-#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
-# if defined(__FreeBSD__)
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_C11_FEATURES
-# elif defined(__Fuchsia__)
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_C11_FEATURES
-# 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
-# endif
-# else // defined(_LIBCPP_HAS_MUSL_LIBC)
-# define _LIBCPP_HAS_QUICK_EXIT
-# define _LIBCPP_HAS_C11_FEATURES
-# endif
-# endif // __linux__
-#endif
-
#if !(__has_feature(cxx_noexcept))
#define _LIBCPP_HAS_NO_NOEXCEPT
#endif
@@ -464,16 +479,6 @@ typedef __char32_t char32_t;
#define _LIBCPP_IS_LITERAL(T) __is_literal(T)
#endif
-// Inline namespaces are available in Clang regardless of C++ dialect.
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
- inline namespace _LIBCPP_NAMESPACE {
- }
-}
-
#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
#define _LIBCPP_HAS_NO_ASAN
#endif
@@ -493,10 +498,15 @@ namespace std {
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
+// No apple compilers support ""d and ""y at this time.
+#if _LIBCPP_CLANG_VER < 800 || defined(__apple_build_version__)
+#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS
+#endif
+
#elif defined(_LIBCPP_COMPILER_GCC)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _LIBCPP_NORETURN __attribute__((noreturn))
@@ -563,15 +573,6 @@ namespace std {
#endif // __GXX_EXPERIMENTAL_CXX0X__
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
- inline namespace _LIBCPP_NAMESPACE {
- }
-}
-
#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)
#define _LIBCPP_HAS_NO_ASAN
#endif
@@ -607,13 +608,6 @@ namespace std {
#define _ALIGNAS_TYPE(x) alignas(x)
#define _LIBCPP_HAS_NO_VARIADICS
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
-#define _LIBCPP_END_NAMESPACE_STD }
-#define _VSTD std
-
-namespace std {
-}
-
#define _LIBCPP_WEAK
#define _LIBCPP_HAS_NO_ASAN
@@ -625,7 +619,7 @@ namespace std {
#elif defined(_LIBCPP_COMPILER_IBM)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _ATTRIBUTE(x) __attribute__((x))
#define _LIBCPP_NORETURN __attribute__((noreturn))
@@ -641,15 +635,6 @@ namespace std {
#define __MULTILOCALE_API
#endif
-#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
-#define _LIBCPP_END_NAMESPACE_STD } }
-#define _VSTD std::_LIBCPP_NAMESPACE
-
-namespace std {
- inline namespace _LIBCPP_NAMESPACE {
- }
-}
-
#define _LIBCPP_HAS_NO_ASAN
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
@@ -658,20 +643,6 @@ namespace std {
#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
-#if _LIBCPP_STD_VER >= 17
-#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
-#else
-#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
- _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
-#endif
-
-#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
- _LIBCPP_END_NAMESPACE_STD } }
-
-#define _VSTD_FS _VSTD::__fs::filesystem
-
-
#if defined(_LIBCPP_OBJECT_FORMAT_COFF)
#ifdef _DLL
@@ -685,33 +656,29 @@ namespace std {
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI
#elif defined(_LIBCPP_BUILDING_LIBRARY)
# define _LIBCPP_DLL_VIS __declspec(dllexport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
#else
# define _LIBCPP_DLL_VIS __declspec(dllimport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
+# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
#endif
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
-#define _LIBCPP_EXTERN_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
#define _LIBCPP_HIDDEN
#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
#define _LIBCPP_TEMPLATE_VIS
#define _LIBCPP_ENUM_VIS
-#if defined(_LIBCPP_COMPILER_MSVC)
-# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline
-#else
-# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__))
-#endif
-
#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
#ifndef _LIBCPP_HIDDEN
@@ -759,8 +726,12 @@ namespace std {
# endif
#endif
-#ifndef _LIBCPP_EXTERN_VIS
-#define _LIBCPP_EXTERN_VIS
+#ifndef _LIBCPP_EXPORTED_FROM_ABI
+# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
+# else
+# define _LIBCPP_EXPORTED_FROM_ABI
+# endif
#endif
#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
@@ -801,21 +772,63 @@ namespace std {
# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
#endif
-#ifndef _LIBCPP_HIDE_FROM_ABI
-# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
+#if __has_attribute(exclude_from_explicit_instantiation)
+# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__))
+#else
+ // Try to approximate the effect of exclude_from_explicit_instantiation
+ // (which is that entities are not assumed to be provided by explicit
+ // template instantitations in the dylib) by always inlining those entities.
+# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
#endif
-// Just so we can migrate to _LIBCPP_HIDE_FROM_ABI gradually.
-#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
+#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
+# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
+# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
+# else
+# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
+# endif
+#endif
-#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
-# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__))
+#ifndef _LIBCPP_HIDE_FROM_ABI
+# if _LIBCPP_HIDE_FROM_ABI_PER_TU
+# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
# else
-# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__))
+# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
#endif
+#ifdef _LIBCPP_BUILDING_LIBRARY
+# if _LIBCPP_ABI_VERSION > 1
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+# else
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
+# endif
+#else
+# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
+#endif
+
+// Just so we can migrate to the new macros gradually.
+#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
+
+// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD } }
+#define _VSTD std::_LIBCPP_ABI_NAMESPACE
+_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 17
+#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+ _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
+#else
+#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
+ _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
+#endif
+
+#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
+ _LIBCPP_END_NAMESPACE_STD } }
+
+#define _VSTD_FS _VSTD::__fs::filesystem
+
#ifndef _LIBCPP_PREFERRED_OVERLOAD
# if __has_attribute(__enable_if__)
# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
@@ -976,7 +989,14 @@ template <unsigned> struct __static_assert_check {};
// If we are getting operator new from the MSVC CRT, then allocation overloads
// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
-#define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+#elif defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
+# define _LIBCPP_DEFER_NEW_TO_VCRUNTIME
+# if !defined(__cpp_aligned_new)
+ // We're defering 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
+# endif
#endif
#if defined(__APPLE__)
@@ -984,13 +1004,13 @@ template <unsigned> struct __static_assert_check {};
defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
# endif
-# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
-# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-# endif
-# 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))
+# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif
#if defined(__APPLE__) || defined(__FreeBSD__)
#define _LIBCPP_HAS_DEFAULTRUNELOCALE
@@ -1000,18 +1020,46 @@ template <unsigned> struct __static_assert_check {};
#define _LIBCPP_WCTYPE_IS_MASK
#endif
-#if _LIBCPP_STD_VER > 11
-# define _LIBCPP_DEPRECATED [[deprecated]]
+#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
+#define _LIBCPP_NO_HAS_CHAR8_T
+#endif
+
+// Deprecation macros.
+// Deprecations warnings are only enabled when _LIBCPP_ENABLE_DEPRECATION_WARNINGS is defined.
+#if defined(_LIBCPP_ENABLE_DEPRECATION_WARNINGS)
+# if __has_attribute(deprecated)
+# define _LIBCPP_DEPRECATED __attribute__ ((deprecated))
+# elif _LIBCPP_STD_VER > 11
+# define _LIBCPP_DEPRECATED [[deprecated]]
+# else
+# define _LIBCPP_DEPRECATED
+# endif
#else
# define _LIBCPP_DEPRECATED
#endif
+#if !defined(_LIBCPP_CXX03_LANG)
+# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
+#else
+# define _LIBCPP_DEPRECATED_IN_CXX11
+#endif
+
+#if _LIBCPP_STD_VER >= 14
+# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
+#else
+# define _LIBCPP_DEPRECATED_IN_CXX14
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
+#else
+# define _LIBCPP_DEPRECATED_IN_CXX17
+#endif
+
#if _LIBCPP_STD_VER <= 11
# define _LIBCPP_EXPLICIT_AFTER_CXX11
-# define _LIBCPP_DEPRECATED_AFTER_CXX11
#else
# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
-# define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
#endif
#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
@@ -1032,8 +1080,30 @@ template <unsigned> struct __static_assert_check {};
# define _LIBCPP_CONSTEXPR_AFTER_CXX17
#endif
-#if __has_cpp_attribute(nodiscard) && _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17)
-# define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]]
+// 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]]
+#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
+#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
+#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
#else
# define _LIBCPP_NODISCARD_AFTER_CXX17
#endif
@@ -1090,6 +1160,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
defined(__Fuchsia__) || \
defined(__NetBSD__) || \
defined(__linux__) || \
+ defined(__GNU__) || \
defined(__APPLE__) || \
defined(__CloudABI__) || \
defined(__sun__) || \
@@ -1195,8 +1266,12 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_DIAGNOSE_ERROR(...)
#endif
-#if __has_attribute(fallthough) || _GNUC_VER >= 700
// Use a function like macro to imply that it must be followed by a semicolon
+#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
+# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
+#elif __has_cpp_attribute(clang::fallthrough)
+# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]]
+#elif __has_attribute(fallthough) || _GNUC_VER >= 700
# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
#else
# define _LIBCPP_FALLTHROUGH() ((void)0)
@@ -1250,9 +1325,15 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
__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__((unavailable))
-# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable))
-# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST __attribute__((unavailable))
+# 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))) \
@@ -1276,8 +1357,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
__attribute__((availability(ios,strict,introduced=7.0)))
#else
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
+# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
-# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
@@ -1289,26 +1370,30 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
// Define availability that depends on _LIBCPP_NO_EXCEPTIONS.
#ifdef _LIBCPP_NO_EXCEPTIONS
-# define _LIBCPP_AVAILABILITY_DYNARRAY
# 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_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
-# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR
-# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST \
- _LIBCPP_AVAILABILITY_BAD_ANY_CAST
-#endif
-
-// Availability of stream API in the dylib got dropped and re-added. The
-// extern template should effectively be available at:
-// availability(macosx,introduced=10.9)
-// availability(ios,introduced=7.0)
-#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) && \
+# 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_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
+# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
#endif
#if defined(_LIBCPP_COMPILER_IBM)
@@ -1351,6 +1436,8 @@ _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))
+
#endif // __cplusplus
#endif // _LIBCPP_CONFIG
diff --git a/include/__config_site.in b/include/__config_site.in
index 8d980ff57cc8..580a6aa4c07b 100644
--- a/include/__config_site.in
+++ b/include/__config_site.in
@@ -14,6 +14,7 @@
#cmakedefine _LIBCPP_ABI_UNSTABLE
#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
@@ -27,6 +28,7 @@
#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
#cmakedefine _LIBCPP_NO_VCRUNTIME
+#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
@_LIBCPP_ABI_DEFINES@
diff --git a/include/__debug b/include/__debug
index d01bacdf7edc..a8788f68f8f4 100644
--- a/include/__debug
+++ b/include/__debug
@@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
/// fails.
-extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
+extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
/// __libcpp_abort_debug_function - A debug handler that aborts when called.
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
diff --git a/include/__functional_base b/include/__functional_base
index 57fdf2b9f663..032be99bf6a5 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -50,7 +50,7 @@ template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
{
- _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x < __y;}
};
@@ -59,7 +59,7 @@ struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
template <>
struct _LIBCPP_TEMPLATE_VIS less<void>
{
- template <class _T1, class _T2>
+ template <class _T1, class _T2>
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
auto operator()(_T1&& __t, _T2&& __u) const
_NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
@@ -552,7 +552,7 @@ template <class _Tp, class, class = void>
struct __is_transparent : false_type {};
template <class _Tp, class _Up>
-struct __is_transparent<_Tp, _Up,
+struct __is_transparent<_Tp, _Up,
typename __void_t<typename _Tp::is_transparent>::type>
: true_type {};
#endif
@@ -562,7 +562,7 @@ struct __is_transparent<_Tp, _Up,
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern const allocator_arg_t allocator_arg;
+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
diff --git a/include/__hash_table b/include/__hash_table
index c77de961be6b..6f5b183105e6 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -35,15 +35,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _Tp>
struct __hash_value_type;
-template <class _Key, class _Cp, class _Hash,
- bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
-class __unordered_map_hasher;
-
-template <class _Key, class _Cp, class _Pred,
- bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
- >
-class __unordered_map_equal;
-
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp>
struct __is_hash_value_type_imp : false_type {};
@@ -418,7 +409,7 @@ public:
_LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this));
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
__hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
: __node_(__x.__node_)
{
@@ -871,35 +862,32 @@ struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
};
#endif
+template <class _Key, class _Hash, class _Equal>
+struct __enforce_unordered_container_requirements {
#ifndef _LIBCPP_CXX03_LANG
-template <class _Key, class _Hash, class _Equal, class _Alloc>
-struct __diagnose_hash_table_helper {
- static constexpr bool __trigger_diagnostics()
- _LIBCPP_DIAGNOSE_WARNING(__check_hash_requirements<_Key, _Hash>::value
- && !__invokable<_Hash const&, _Key const&>::value,
- "the specified hash functor does not provide a const call operator")
- _LIBCPP_DIAGNOSE_WARNING(is_copy_constructible<_Equal>::value
- && !__invokable<_Equal const&, _Key const&, _Key const&>::value,
- "the specified comparator type does not provide a const call operator")
- {
static_assert(__check_hash_requirements<_Key, _Hash>::value,
- "the specified hash does not meet the Hash requirements");
+ "the specified hash does not meet the Hash requirements");
static_assert(is_copy_constructible<_Equal>::value,
- "the specified comparator is required to be copy constructible");
- return true;
- }
+ "the specified comparator is required to be copy constructible");
+#endif
+ typedef int type;
};
-template <class _Key, class _Value, class _Hash, class _Equal, class _Alloc>
-struct __diagnose_hash_table_helper<
- __hash_value_type<_Key, _Value>,
- __unordered_map_hasher<_Key, __hash_value_type<_Key, _Value>, _Hash>,
- __unordered_map_equal<_Key, __hash_value_type<_Key, _Value>, _Equal>,
- _Alloc>
-: __diagnose_hash_table_helper<_Key, _Hash, _Equal, _Alloc>
-{
-};
-#endif // _LIBCPP_CXX03_LANG
+template <class _Key, class _Hash, class _Equal>
+#ifndef _LIBCPP_CXX03_LANG
+ _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
+ "the specified comparator type does not provide a const call operator")
+ _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
+ "the specified hash functor does not provide a const call operator")
+#endif
+typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
+__diagnose_unordered_container_requirements(int);
+
+// This dummy overload is used so that the compiler won't emit a spurious
+// "no matching function for call to __diagnose_unordered_xxx" diagnostic
+// when the overload above causes a hard error.
+template <class _Key, class _Hash, class _Equal>
+int __diagnose_unordered_container_requirements(void*);
template <class _Tp, class _Hash, class _Equal, class _Alloc>
class __hash_table
@@ -963,10 +951,6 @@ private:
typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits;
typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
-#ifndef _LIBCPP_CXX03_LANG
- static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), "");
-#endif
-
// --- Member data begin ---
__bucket_list __bucket_list_;
__compressed_pair<__first_node, __node_allocator> __p1_;
@@ -1058,8 +1042,26 @@ public:
);
}
+private:
+ _LIBCPP_INLINE_VISIBILITY
+ __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
+ value_type& __cp_val);
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_insert_multi_perform(__node_pointer __cp,
+ __next_pointer __pn) _NOEXCEPT;
+
+ _LIBCPP_INLINE_VISIBILITY
+ __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
+ value_type& __nd_val);
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
+
+public:
+ _LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
+ _LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(__node_pointer __nd);
+ _LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(const_iterator __p,
__node_pointer __nd);
@@ -1170,6 +1172,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_unique(const_iterator __hint,
_NodeHandle&& __nh);
+ template <class _Table>
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_handle_merge_unique(_Table& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
@@ -1177,6 +1182,9 @@ public:
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
+ template <class _Table>
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_handle_merge_multi(_Table& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
@@ -1849,73 +1857,112 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
}
}
+
+// Prepare the container for an insertion of the value __value with the hash
+// __hash. This does a lookup into the container to see if __value is already
+// present, and performs a rehash if necessary. Returns a pointer to the
+// existing element if it exists, otherwise nullptr.
+//
+// Note that this function does forward exceptions if key_eq() throws, and never
+// mutates __value or actually inserts into the map.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
+_LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
+ size_t __hash, value_type& __value)
{
- __nd->__hash_ = hash_function()(__nd->__value_);
size_type __bc = bucket_count();
- bool __inserted = false;
- __next_pointer __ndptr;
- size_t __chash;
+
if (__bc != 0)
{
- __chash = __constrain_hash(__nd->__hash_, __bc);
- __ndptr = __bucket_list_[__chash];
+ size_t __chash = __constrain_hash(__hash, __bc);
+ __next_pointer __ndptr = __bucket_list_[__chash];
if (__ndptr != nullptr)
{
for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
__constrain_hash(__ndptr->__hash(), __bc) == __chash;
__ndptr = __ndptr->__next_)
{
- if (key_eq()(__ndptr->__upcast()->__value_, __nd->__value_))
- goto __done;
+ if (key_eq()(__ndptr->__upcast()->__value_, __value))
+ return __ndptr;
}
}
}
+ if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- if (size()+1 > __bc * max_load_factor() || __bc == 0)
- {
- rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
- size_type(ceil(float(size() + 1) / max_load_factor()))));
- __bc = bucket_count();
- __chash = __constrain_hash(__nd->__hash_, __bc);
- }
- // insert_after __bucket_list_[__chash], or __first_node if bucket is null
- __next_pointer __pn = __bucket_list_[__chash];
- if (__pn == nullptr)
- {
- __pn =__p1_.first().__ptr();
- __nd->__next_ = __pn->__next_;
- __pn->__next_ = __nd->__ptr();
- // fix up __bucket_list_
- __bucket_list_[__chash] = __pn;
- if (__nd->__next_ != nullptr)
- __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
- }
- else
- {
- __nd->__next_ = __pn->__next_;
- __pn->__next_ = __nd->__ptr();
- }
- __ndptr = __nd->__ptr();
- // increment size
- ++size();
+ rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
+ size_type(ceil(float(size() + 1) / max_load_factor()))));
+ }
+ return nullptr;
+}
+
+// Insert the node __nd into the container by pushing it into the right bucket,
+// and updating size(). Assumes that __nd->__hash is up-to-date, and that
+// rehashing has already occurred and that no element with the same key exists
+// in the map.
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
+ __node_pointer __nd) _NOEXCEPT
+{
+ size_type __bc = bucket_count();
+ size_t __chash = __constrain_hash(__nd->__hash(), __bc);
+ // insert_after __bucket_list_[__chash], or __first_node if bucket is null
+ __next_pointer __pn = __bucket_list_[__chash];
+ if (__pn == nullptr)
+ {
+ __pn =__p1_.first().__ptr();
+ __nd->__next_ = __pn->__next_;
+ __pn->__next_ = __nd->__ptr();
+ // fix up __bucket_list_
+ __bucket_list_[__chash] = __pn;
+ if (__nd->__next_ != nullptr)
+ __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
+ }
+ else
+ {
+ __nd->__next_ = __pn->__next_;
+ __pn->__next_ = __nd->__ptr();
+ }
+ ++size();
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
+{
+ __nd->__hash_ = hash_function()(__nd->__value_);
+ __next_pointer __existing_node =
+ __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
+
+ // Insert the node, unless it already exists in the container.
+ bool __inserted = false;
+ if (__existing_node == nullptr)
+ {
+ __node_insert_unique_perform(__nd);
+ __existing_node = __nd->__ptr();
__inserted = true;
}
-__done:
#if _LIBCPP_DEBUG_LEVEL >= 2
- return pair<iterator, bool>(iterator(__ndptr, this), __inserted);
+ return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
#else
- return pair<iterator, bool>(iterator(__ndptr), __inserted);
+ return pair<iterator, bool>(iterator(__existing_node), __inserted);
#endif
}
+// 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.
+//
+// Note that this function does forward exceptions if key_eq() throws, and never
+// mutates __value or actually inserts into the map.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
+ size_t __cp_hash, value_type& __cp_val)
{
- __cp->__hash_ = hash_function()(__cp->__value_);
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
@@ -1923,20 +1970,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
- size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+ size_t __chash = __constrain_hash(__cp_hash, __bc);
__next_pointer __pn = __bucket_list_[__chash];
- if (__pn == nullptr)
- {
- __pn =__p1_.first().__ptr();
- __cp->__next_ = __pn->__next_;
- __pn->__next_ = __cp->__ptr();
- // fix up __bucket_list_
- __bucket_list_[__chash] = __pn;
- if (__cp->__next_ != nullptr)
- __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
- = __cp->__ptr();
- }
- else
+ if (__pn != nullptr)
{
for (bool __found = false; __pn->__next_ != nullptr &&
__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
@@ -1947,8 +1983,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
// true true loop
// false true set __found to true
// true false break
- if (__found != (__pn->__next_->__hash() == __cp->__hash_ &&
- key_eq()(__pn->__next_->__upcast()->__value_, __cp->__value_)))
+ if (__found != (__pn->__next_->__hash() == __cp_hash &&
+ key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
{
if (!__found)
__found = true;
@@ -1956,6 +1992,35 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
break;
}
}
+ }
+ return __pn;
+}
+
+// Insert the node __cp into the container after __pn (which is the last node in
+// the bucket that compares equal to __cp). Rehashing, and checking for
+// uniqueness has already been performed (in __node_insert_multi_prepare), so
+// all we need to do is update the bucket and size(). Assumes that __cp->__hash
+// is up-to-date.
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
+ __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
+{
+ size_type __bc = bucket_count();
+ size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+ if (__pn == nullptr)
+ {
+ __pn =__p1_.first().__ptr();
+ __cp->__next_ = __pn->__next_;
+ __pn->__next_ = __cp->__ptr();
+ // fix up __bucket_list_
+ __bucket_list_[__chash] = __pn;
+ if (__cp->__next_ != nullptr)
+ __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
+ = __cp->__ptr();
+ }
+ else
+ {
__cp->__next_ = __pn->__next_;
__pn->__next_ = __cp->__ptr();
if (__cp->__next_ != nullptr)
@@ -1966,6 +2031,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
}
}
++size();
+}
+
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
+{
+ __cp->__hash_ = hash_function()(__cp->__value_);
+ __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
+ __node_insert_multi_perform(__cp, __pn);
+
#if _LIBCPP_DEBUG_LEVEL >= 2
return iterator(__cp->__ptr(), this);
#else
@@ -2217,6 +2293,32 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Table>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
+ _Table& __source)
+{
+ static_assert(is_same<__node, typename _Table::__node>::value, "");
+
+ for (typename _Table::iterator __it = __source.begin();
+ __it != __source.end();)
+ {
+ __node_pointer __src_ptr = __it.__node_->__upcast();
+ size_t __hash = hash_function()(__src_ptr->__value_);
+ __next_pointer __existing_node =
+ __node_insert_unique_prepare(__hash, __src_ptr->__value_);
+ auto __prev_iter = __it++;
+ if (__existing_node == nullptr)
+ {
+ (void)__source.remove(__prev_iter).release();
+ __src_ptr->__hash_ = __hash;
+ __node_insert_unique_perform(__src_ptr);
+ }
+ }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
@@ -2244,6 +2346,27 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
return __result;
}
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Table>
+_LIBCPP_INLINE_VISIBILITY
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
+ _Table& __source)
+{
+ static_assert(is_same<typename _Table::__node, __node>::value, "");
+
+ for (typename _Table::iterator __it = __source.begin();
+ __it != __source.end();)
+ {
+ __node_pointer __src_ptr = __it.__node_->__upcast();
+ size_t __src_hash = hash_function()(__src_ptr->__value_);
+ __next_pointer __pn =
+ __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
+ (void)__source.remove(__it++).release();
+ __src_ptr->__hash_ = __src_hash;
+ __node_insert_multi_perform(__src_ptr, __pn);
+ }
+}
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
diff --git a/include/__libcpp_version b/include/__libcpp_version
index 2bdc6533bec7..e002b3628b34 100644
--- a/include/__libcpp_version
+++ b/include/__libcpp_version
@@ -1 +1 @@
-7000
+8000
diff --git a/include/__locale b/include/__locale
index f43e7b4303d3..cde9cc85f6b5 100644
--- a/include/__locale
+++ b/include/__locale
@@ -1255,13 +1255,13 @@ struct __narrow_to_utf8<8>
};
template <>
-struct __narrow_to_utf8<16>
+struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
- ~__narrow_to_utf8();
+ _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_INLINE_VISIBILITY
@@ -1289,13 +1289,13 @@ struct __narrow_to_utf8<16>
};
template <>
-struct __narrow_to_utf8<32>
+struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
- ~__narrow_to_utf8();
+ _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_INLINE_VISIBILITY
@@ -1345,13 +1345,13 @@ struct __widen_from_utf8<8>
};
template <>
-struct __widen_from_utf8<16>
+struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
- ~__widen_from_utf8();
+ _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_INLINE_VISIBILITY
@@ -1379,13 +1379,13 @@ struct __widen_from_utf8<16>
};
template <>
-struct __widen_from_utf8<32>
+struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
- ~__widen_from_utf8();
+ _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_INLINE_VISIBILITY
diff --git a/include/__mutex_base b/include/__mutex_base
index 4659ca9298c9..da21a5f8eb6a 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -76,9 +76,9 @@ struct _LIBCPP_TYPE_VIS adopt_lock_t {};
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern const defer_lock_t defer_lock;
-extern const try_to_lock_t try_to_lock;
-extern const adopt_lock_t adopt_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
+extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock;
#else
diff --git a/include/__node_handle b/include/__node_handle
index fe09f3c1e51c..a9cf3b7217a3 100644
--- a/include/__node_handle
+++ b/include/__node_handle
@@ -26,8 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
-#define __cpp_lib_node_extract 201606L
-
// Specialized in __tree & __hash_table for their _NodeType.
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
diff --git a/include/__sso_allocator b/include/__sso_allocator
index 40027363a185..8aca0495d756 100644
--- a/include/__sso_allocator
+++ b/include/__sso_allocator
@@ -55,14 +55,14 @@ public:
__allocated_ = true;
return (pointer)&buf_;
}
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
- _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
+ _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
{
if (__p == (pointer)&buf_)
__allocated_ = false;
else
- _VSTD::__libcpp_deallocate(__p, __alignof(_Tp));
+ _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
diff --git a/include/__string b/include/__string
index 44c55987f9f7..1ddeec7149fb 100644
--- a/include/__string
+++ b/include/__string
@@ -47,6 +47,7 @@ struct char_traits
template <> struct char_traits<char>;
template <> struct char_traits<wchar_t>;
+template <> struct char_traits<char8_t>; // c++20
} // std
@@ -389,6 +390,102 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
+{
+ typedef char8_t char_type;
+ typedef unsigned int int_type;
+ typedef streamoff off_type;
+ typedef u8streampos pos_type;
+ typedef mbstate_t state_type;
+
+ static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
+ {__c1 = __c2;}
+ static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
+ {return __c1 == __c2;}
+ static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
+ {return __c1 < __c2;}
+
+ static constexpr
+ int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+
+ static constexpr
+ size_t length(const char_type* __s) _NOEXCEPT;
+
+ _LIBCPP_INLINE_VISIBILITY static constexpr
+ const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
+ static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+ {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
+
+ static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+ {
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
+ }
+
+ static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+ {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
+
+ static inline constexpr int_type not_eof(int_type __c) noexcept
+ {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+ static inline constexpr char_type to_char_type(int_type __c) noexcept
+ {return char_type(__c);}
+ static inline constexpr int_type to_int_type(char_type __c) noexcept
+ {return int_type(__c);}
+ static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
+ {return __c1 == __c2;}
+ static inline constexpr int_type eof() noexcept
+ {return int_type(EOF);}
+};
+
+// TODO use '__builtin_strlen' if it ever supports char8_t ??
+inline constexpr
+size_t
+char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
+{
+ size_t __len = 0;
+ for (; !eq(*__s, char_type(0)); ++__s)
+ ++__len;
+ return __len;
+}
+
+inline constexpr
+int
+char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+#if __has_feature(cxx_constexpr_string_builtins)
+ return __builtin_memcmp(__s1, __s2, __n);
+#else
+ for (; __n; --__n, ++__s1, ++__s2)
+ {
+ if (lt(*__s1, *__s2))
+ return -1;
+ if (lt(*__s2, *__s1))
+ return 1;
+ }
+ return 0;
+#endif
+}
+
+// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
+inline constexpr
+const char8_t*
+char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+ for (; __n; --__n)
+ {
+ if (eq(*__s, __a))
+ return __s;
+ ++__s;
+ }
+ return 0;
+}
+
+#endif // #_LIBCPP_NO_HAS_CHAR8_T
+
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <>
diff --git a/include/__threading_support b/include/__threading_support
index 3c1eff22f530..202490062729 100644
--- a/include/__threading_support
+++ b/include/__threading_support
@@ -70,7 +70,7 @@ typedef pthread_t __libcpp_thread_id;
typedef pthread_t __libcpp_thread_t;
-// Thrad Local Storage
+// Thread Local Storage
typedef pthread_key_t __libcpp_tls_key;
#define _LIBCPP_TLS_DESTRUCTOR_CC
diff --git a/include/__tree b/include/__tree
index af9b9616df8a..814851085b98 100644
--- a/include/__tree
+++ b/include/__tree
@@ -40,10 +40,6 @@ template <class _Tp, class _VoidPtr> class __tree_node;
template <class _Key, class _Value>
struct __value_type;
-template <class _Key, class _CP, class _Compare,
- bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
-class __map_value_compare;
-
template <class _Allocator> class __map_node_destructor;
template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
@@ -857,7 +853,7 @@ public:
__tree_iterator operator--(int)
{__tree_iterator __t(*this); --(*this); return __t;}
- friend _LIBCPP_INLINE_VISIBILITY
+ friend _LIBCPP_INLINE_VISIBILITY
bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
{return __x.__ptr_ == __y.__ptr_;}
friend _LIBCPP_INLINE_VISIBILITY
@@ -966,24 +962,12 @@ private:
};
+template<class _Tp, class _Compare>
#ifndef _LIBCPP_CXX03_LANG
-template <class _Tp, class _Compare, class _Allocator>
-struct __diagnose_tree_helper {
- static constexpr bool __trigger_diagnostics()
- _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
- "the specified comparator type does not provide a const call operator")
- { return true; }
-};
-
-template <class _Key, class _Value, class _KeyComp, class _Alloc>
-struct __diagnose_tree_helper<
- __value_type<_Key, _Value>,
- __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>,
- _Alloc
-> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc>
-{
-};
-#endif // !_LIBCPP_CXX03_LANG
+ _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
+ "the specified comparator type does not provide a const call operator")
+#endif
+int __diagnose_non_const_comparator();
template <class _Tp, class _Compare, class _Allocator>
class __tree
@@ -1341,15 +1325,20 @@ public:
#endif // !_LIBCPP_CXX03_LANG
+ _LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
+ _LIBCPP_INLINE_VISIBILITY
iterator __node_insert_unique(const_iterator __p,
__node_pointer __nd);
+ _LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(__node_pointer __nd);
+ _LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
- _LIBCPP_INLINE_VISIBILITY iterator __remove_node_pointer(__node_pointer);
+ _LIBCPP_INLINE_VISIBILITY iterator
+ __remove_node_pointer(__node_pointer) _NOEXCEPT;
#if _LIBCPP_STD_VER > 14
template <class _NodeHandle, class _InsertReturnType>
@@ -1358,6 +1347,9 @@ public:
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
+ template <class _Tree>
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_handle_merge_unique(_Tree& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
@@ -1365,6 +1357,9 @@ public:
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
+ template <class _Tree>
+ _LIBCPP_INLINE_VISIBILITY
+ void __node_handle_merge_multi(_Tree& __source);
template <class _NodeHandle>
@@ -1384,7 +1379,7 @@ public:
void __insert_node_at(__parent_pointer __parent,
__node_base_pointer& __child,
- __node_base_pointer __new_node);
+ __node_base_pointer __new_node) _NOEXCEPT;
template <class _Key>
iterator find(const _Key& __v);
@@ -1488,7 +1483,7 @@ private:
void __copy_assign_alloc(const __tree& __t, true_type)
{
if (__node_alloc() != __t.__node_alloc())
- clear();
+ clear();
__node_alloc() = __t.__node_alloc();
}
_LIBCPP_INLINE_VISIBILITY
@@ -1830,7 +1825,7 @@ __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
__node_traits::propagate_on_container_move_assignment::value &&
is_nothrow_move_assignable<value_compare>::value &&
is_nothrow_move_assignable<__node_allocator>::value)
-
+
{
__move_assign(__t, integral_constant<bool,
__node_traits::propagate_on_container_move_assignment::value>());
@@ -1844,10 +1839,6 @@ __tree<_Tp, _Compare, _Allocator>::~__tree()
{
static_assert((is_copy_constructible<value_compare>::value),
"Comparator must be copy-constructible.");
-#ifndef _LIBCPP_CXX03_LANG
- static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
- __trigger_diagnostics()), "");
-#endif
destroy(__root());
}
@@ -2129,10 +2120,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
}
template <class _Tp, class _Compare, class _Allocator>
-void
-__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent,
- __node_base_pointer& __child,
- __node_base_pointer __new_node)
+void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
+ __parent_pointer __parent, __node_base_pointer& __child,
+ __node_base_pointer __new_node) _NOEXCEPT
{
__new_node->__left_ = nullptr;
__new_node->__right_ = nullptr;
@@ -2384,7 +2374,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr)
+__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
{
iterator __r(__ptr);
++__r;
@@ -2472,6 +2462,30 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
}
template <class _Tp, class _Compare, class _Allocator>
+template <class _Tree>
+_LIBCPP_INLINE_VISIBILITY
+void
+__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
+{
+ static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
+
+ for (typename _Tree::iterator __i = __source.begin();
+ __i != __source.end();)
+ {
+ __node_pointer __src_ptr = __i.__get_np();
+ __parent_pointer __parent;
+ __node_base_pointer& __child =
+ __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
+ ++__i;
+ if (__child != nullptr)
+ continue;
+ __source.__remove_node_pointer(__src_ptr);
+ __insert_node_at(__parent, __child,
+ static_cast<__node_base_pointer>(__src_ptr));
+ }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __tree<_Tp, _Compare, _Allocator>::iterator
@@ -2507,6 +2521,28 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
return iterator(__ptr);
}
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Tree>
+_LIBCPP_INLINE_VISIBILITY
+void
+__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
+{
+ static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
+
+ for (typename _Tree::iterator __i = __source.begin();
+ __i != __source.end();)
+ {
+ __node_pointer __src_ptr = __i.__get_np();
+ __parent_pointer __parent;
+ __node_base_pointer& __child = __find_leaf_high(
+ __parent, _NodeTypes::__get_key(__src_ptr->__value_));
+ ++__i;
+ __source.__remove_node_pointer(__src_ptr);
+ __insert_node_at(__parent, __child,
+ static_cast<__node_base_pointer>(__src_ptr));
+ }
+}
+
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Compare, class _Allocator>
diff --git a/include/__tuple b/include/__tuple
index 69d6ee961113..3b23d78afa1b 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -22,36 +22,36 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size;
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
#if !defined(_LIBCPP_CXX03_LANG)
template <class _Tp, class...>
using __enable_if_tuple_size_imp = _Tp;
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
const _Tp,
typename enable_if<!is_volatile<_Tp>::value>::type,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
volatile _Tp,
typename enable_if<!is_const<_Tp>::value>::type,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
const volatile _Tp,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
#else
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
-template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
#endif
template <size_t _Ip, class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_element;
@@ -165,7 +165,7 @@ template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple;
template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
template <class ..._Tp>
-class _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
+struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
: public integral_constant<size_t, sizeof...(_Tp)>
{
};
@@ -291,7 +291,7 @@ public:
template <class ..._Tp>
-class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
+struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
: public integral_constant<size_t, sizeof...(_Tp)>
{
};
diff --git a/include/algorithm b/include/algorithm
index 90f1d246c63d..d102899f2dfc 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -645,13 +645,8 @@ template <class BidirectionalIterator, class Compare>
#include <functional>
#include <iterator>
#include <cstddef>
-
-#if defined(__IBMCPP__)
-#include "support/ibm/support.h"
-#endif
-#if defined(_LIBCPP_COMPILER_MSVC)
-#include <intrin.h>
-#endif
+#include <bit>
+#include <version>
#include <__debug>
@@ -755,6 +750,32 @@ public:
bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
};
+// Perform division by two quickly for positive integers (llvm.org/PR39129)
+
+template <typename _Integral>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+ is_integral<_Integral>::value,
+ _Integral
+>::type
+__half_positive(_Integral __value)
+{
+ return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2);
+}
+
+template <typename _Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+typename enable_if
+<
+ !is_integral<_Tp>::value,
+ _Tp
+>::type
+__half_positive(_Tp __value)
+{
+ return __value / 2;
+}
+
#ifdef _LIBCPP_DEBUG
template <class _Compare>
@@ -788,135 +809,6 @@ struct __debug_less
#endif // _LIBCPP_DEBUG
-// Precondition: __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned __ctz(unsigned __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned>(__builtin_ctz(__x));
-#else
- static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
- static_assert(sizeof(unsigned long) == 4, "");
- unsigned long where;
- // Search from LSB to MSB for first set bit.
- // Returns zero if no set bit is found.
- if (_BitScanForward(&where, __x))
- return where;
- return 32;
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long __ctz(unsigned long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned long>(__builtin_ctzl(__x));
-#else
- static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
- return __ctz(static_cast<unsigned>(__x));
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long long __ctz(unsigned long long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned long long>(__builtin_ctzll(__x));
-#else
- unsigned long where;
-// Search from LSB to MSB for first set bit.
-// Returns zero if no set bit is found.
-#if defined(_LIBCPP_HAS_BITSCAN64)
- (defined(_M_AMD64) || defined(__x86_64__))
- if (_BitScanForward64(&where, __x))
- return static_cast<int>(where);
-#else
- // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
- // Scan the Low Word.
- if (_BitScanForward(&where, static_cast<unsigned long>(__x)))
- return where;
- // Scan the High Word.
- if (_BitScanForward(&where, static_cast<unsigned long>(__x >> 32)))
- return where + 32; // Create a bit offset from the LSB.
-#endif
- return 64;
-#endif // _LIBCPP_COMPILER_MSVC
-}
-
-// Precondition: __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned __clz(unsigned __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned>(__builtin_clz(__x));
-#else
- static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
- static_assert(sizeof(unsigned long) == 4, "");
- unsigned long where;
- // Search from LSB to MSB for first set bit.
- // Returns zero if no set bit is found.
- if (_BitScanReverse(&where, __x))
- return 31 - where;
- return 32; // Undefined Behavior.
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long __clz(unsigned long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned long>(__builtin_clzl (__x));
-#else
- static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
- return __clz(static_cast<unsigned>(__x));
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-unsigned long long __clz(unsigned long long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return static_cast<unsigned long long>(__builtin_clzll(__x));
-#else
- unsigned long where;
-// BitScanReverse scans from MSB to LSB for first set bit.
-// Returns 0 if no set bit is found.
-#if defined(_LIBCPP_HAS_BITSCAN64)
- if (_BitScanReverse64(&where, __x))
- return static_cast<int>(63 - where);
-#else
- // Scan the high 32 bits.
- if (_BitScanReverse(&where, static_cast<unsigned long>(__x >> 32)))
- return 63 - (where + 32); // Create a bit offset from the MSB.
- // Scan the low 32 bits.
- if (_BitScanReverse(&where, static_cast<unsigned long>(__x)))
- return 63 - where;
-#endif
- return 64; // Undefined Behavior.
-#endif // _LIBCPP_COMPILER_MSVC
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return __builtin_popcount (__x);
-#else
- static_assert(sizeof(unsigned) == 4, "");
- return __popcnt(__x);
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return __builtin_popcountl (__x);
-#else
- static_assert(sizeof(unsigned long) == 4, "");
- return __popcnt(__x);
-#endif
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {
-#ifndef _LIBCPP_COMPILER_MSVC
- return __builtin_popcountll(__x);
-#else
- static_assert(sizeof(unsigned long long) == 8, "");
- return __popcnt64(__x);
-#endif
-}
-
// all_of
template <class _InputIterator, class _Predicate>
@@ -2533,6 +2425,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
+ static_assert(__is_forward_iterator<_ForwardIterator>::value,
+ "std::min_element requires a ForwardIterator");
if (__first != __last)
{
_ForwardIterator __i = __first;
@@ -2597,6 +2491,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
+ static_assert(__is_forward_iterator<_ForwardIterator>::value,
+ "std::max_element requires a ForwardIterator");
if (__first != __last)
{
_ForwardIterator __i = __first;
@@ -2683,6 +2579,8 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
+ static_assert(__is_forward_iterator<_ForwardIterator>::value,
+ "std::minmax_element requires a ForwardIterator");
std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
if (__first != __last)
{
@@ -3027,10 +2925,11 @@ template<class _IntType>
template<class _URNG>
typename uniform_int_distribution<_IntType>::result_type
uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
uint32_t, uint64_t>::type _UIntType;
- const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
+ const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
if (_Rp == 1)
return __p.a();
const size_t _Dt = numeric_limits<_UIntType>::digits;
@@ -3080,7 +2979,7 @@ public:
_LIBCPP_FUNC_VIS __rs_default __rs_get();
template <class _RandomAccessIterator>
-void
+_LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@@ -3101,7 +3000,7 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
}
template <class _RandomAccessIterator, class _RandomNumberGenerator>
-void
+_LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
#ifndef _LIBCPP_CXX03_LANG
_RandomNumberGenerator&& __rand)
@@ -3116,7 +3015,8 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
for (--__last; __first < __last; ++__first, --__d)
{
difference_type __i = __rand(__d);
- swap(*__first, *(__first + __i));
+ if (__i != difference_type(0))
+ swap(*__first, *(__first + __i));
}
}
}
@@ -3328,7 +3228,7 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
- difference_type __l2 = __len / 2;
+ difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__pred(*__m))
@@ -3737,6 +3637,7 @@ __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
// stable, 4-10 compares, 0-9 swaps
template <class _Compare, class _ForwardIterator>
+_LIBCPP_HIDDEN
unsigned
__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
_ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
@@ -4195,7 +4096,7 @@ __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
- difference_type __l2 = __len / 2;
+ difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(*__m, __value_))
@@ -4214,14 +4115,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
{
-#ifdef _LIBCPP_DEBUG
- typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
- __debug_less<_Compare> __c(__comp);
- return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif // _LIBCPP_DEBUG
}
template <class _ForwardIterator, class _Tp>
@@ -4243,7 +4138,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
- difference_type __l2 = __len / 2;
+ difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(__value_, *__m))
@@ -4262,14 +4157,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
{
-#ifdef _LIBCPP_DEBUG
- typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
- __debug_less<_Compare> __c(__comp);
- return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif // _LIBCPP_DEBUG
}
template <class _ForwardIterator, class _Tp>
@@ -4291,7 +4180,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
- difference_type __l2 = __len / 2;
+ difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(*__m, __value_))
diff --git a/include/any b/include/any
index 9bd2f53c5601..781eee7869c0 100644
--- a/include/any
+++ b/include/any
@@ -87,13 +87,14 @@ namespace std {
#include <typeinfo>
#include <type_traits>
#include <cstdlib>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
namespace std {
-class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
+class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
{
public:
virtual const char* what() const _NOEXCEPT;
@@ -105,12 +106,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
void __throw_bad_any_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_any_cast();
#else
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -576,6 +578,7 @@ any make_any(initializer_list<_Up> __il, _Args&&... __args) {
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any const & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@@ -590,6 +593,7 @@ _ValueType any_cast(any const & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@@ -604,6 +608,7 @@ _ValueType any_cast(any & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any && __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
diff --git a/include/array b/include/array
index 1e6a650198b5..56f6887655aa 100644
--- a/include/array
+++ b/include/array
@@ -91,7 +91,7 @@ template <class T, size_t N>
template <class T, size_t N >
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
-template <class T> class tuple_size;
+template <class T> struct tuple_size;
template <size_t I, class T> class tuple_element;
template <class T, size_t N> struct tuple_size<array<T, N>>;
template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
@@ -112,6 +112,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#include <algorithm>
#include <stdexcept>
#include <cstdlib> // for _LIBCPP_UNREACHABLE
+#include <version>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -367,7 +368,7 @@ array(_Tp, _Args...)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
@@ -375,7 +376,7 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__x == __y);
@@ -383,7 +384,7 @@ operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
@@ -392,7 +393,7 @@ operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return __y < __x;
@@ -400,7 +401,7 @@ operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__y < __x);
@@ -408,7 +409,7 @@ operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
-bool
+_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__x < __y);
@@ -429,7 +430,7 @@ swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
}
template <class _Tp, size_t _Size>
-class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
+struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
: public integral_constant<size_t, _Size> {};
template <size_t _Ip, class _Tp, size_t _Size>
diff --git a/include/atomic b/include/atomic
index 809f78a06d36..d37e7b4b035c 100644
--- a/include/atomic
+++ b/include/atomic
@@ -544,6 +544,7 @@ void atomic_signal_fence(memory_order m) noexcept;
#include <cstddef>
#include <cstdint>
#include <type_traits>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -559,10 +560,6 @@ void atomic_signal_fence(memory_order m) noexcept;
#error C++ standard library is incompatible with <stdatomic.h>
#endif
-#if _LIBCPP_STD_VER > 14
-# define __cpp_lib_atomic_is_always_lock_free 201603L
-#endif
-
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
__m == memory_order_acquire || \
diff --git a/include/bit b/include/bit
new file mode 100644
index 000000000000..db3812e5b5b2
--- /dev/null
+++ b/include/bit
@@ -0,0 +1,158 @@
+// -*- C++ -*-
+//===------------------------------ bit ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_BIT
+#define _LIBCPP_BIT
+
+/*
+ bit synopsis
+
+namespace std {
+
+} // namespace std
+
+*/
+
+#include <__config>
+#include <version>
+
+#if defined(__IBMCPP__)
+#include "support/ibm/support.h"
+#endif
+#if defined(_LIBCPP_COMPILER_MSVC)
+#include <intrin.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_COMPILER_MSVC
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __ctz(unsigned __x) { return __builtin_ctz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __ctz(unsigned long __x) { return __builtin_ctzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __ctz(unsigned long long __x) { return __builtin_ctzll(__x); }
+
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __clz(unsigned __x) { return __builtin_clz(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __clz(unsigned long __x) { return __builtin_clzl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __clz(unsigned long long __x) { return __builtin_clzll(__x); }
+
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __popcount(unsigned __x) { return __builtin_popcount(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __popcount(unsigned long __x) { return __builtin_popcountl(__x); }
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __popcount(unsigned long long __x) { return __builtin_popcountll(__x); }
+
+#else // _LIBCPP_COMPILER_MSVC
+
+// Precondition: __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+int __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<int>(__where);
+ return 32;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __ctz(unsigned long __x) {
+ static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
+ return __ctz(static_cast<unsigned>(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __ctz(unsigned long long __x) {
+ unsigned long __where;
+#if defined(_LIBCPP_HAS_BITSCAN64)
+ (defined(_M_AMD64) || defined(__x86_64__))
+ if (_BitScanForward64(&__where, __x))
+ return static_cast<int>(__where);
+#else
+ // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
+ if (_BitScanForward(&__where, static_cast<unsigned long>(__x)))
+ return static_cast<int>(__where);
+ if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32)))
+ return static_cast<int>(__where + 32);
+#endif
+ return 64;
+}
+
+// Precondition: __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+int __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<int>(31 - __where);
+ return 32; // Undefined Behavior.
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __clz(unsigned long __x) {
+ static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+ return __clz(static_cast<unsigned>(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __clz(unsigned long long __x) {
+ unsigned long __where;
+#if defined(_LIBCPP_HAS_BITSCAN64)
+ if (_BitScanReverse64(&__where, __x))
+ return static_cast<int>(63 - __where);
+#else
+ // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls.
+ if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32)))
+ return static_cast<int>(63 - (__where + 32));
+ if (_BitScanReverse(&__where, static_cast<unsigned long>(__x)))
+ return static_cast<int>(63 - __where);
+#endif
+ return 64; // Undefined Behavior.
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned __x) {
+ static_assert(sizeof(unsigned) == 4, "");
+ return __popcnt(__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long __x) {
+ static_assert(sizeof(unsigned long) == 4, "");
+ return __popcnt(__x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long long __x) {
+ static_assert(sizeof(unsigned long long) == 8, "");
+ return __popcnt64(__x);
+}
+
+#endif // _LIBCPP_COMPILER_MSVC
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_BIT
diff --git a/include/bitset b/include/bitset
index cd6c289b4c48..98947e027c1c 100644
--- a/include/bitset
+++ b/include/bitset
@@ -238,9 +238,9 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT
size_t __sz = _Size;
for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word, __sz -= __bits_per_word )
if ( __sz < __bits_per_word)
- __t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1;
+ __t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1;
else
- __t[__i] = static_cast<__storage_type>(__v);
+ __t[__i] = static_cast<__storage_type>(__v);
_VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_);
_VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]),
@@ -254,7 +254,7 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT
{
__first_[0] = __v;
if (_Size < __bits_per_word)
- __first_[0] &= ( 1ULL << _Size ) - 1;
+ __first_[0] &= ( 1ULL << _Size ) - 1;
_VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));
}
@@ -269,9 +269,9 @@ __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
#if __SIZEOF_SIZE_T__ == 8
: __first_{__v}
#elif __SIZEOF_SIZE_T__ == 4
- : __first_{static_cast<__storage_type>(__v),
- _Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word)
- : static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
+ : __first_{static_cast<__storage_type>(__v),
+ _Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word)
+ : static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
#else
#error This constructor has not been ported to this platform
#endif
@@ -991,7 +991,7 @@ inline
size_t
bitset<_Size>::count() const _NOEXCEPT
{
- return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true));
+ return static_cast<size_t>(__count_bool_true(base::__make_iter(0), _Size));
}
template <size_t _Size>
diff --git a/include/charconv b/include/charconv
index 7cb790e1beec..064f2e11c3f3 100644
--- a/include/charconv
+++ b/include/charconv
@@ -87,8 +87,16 @@ namespace std {
#pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __itoa {
+_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
+_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
+}
+
#if _LIBCPP_STD_VER > 11
enum class _LIBCPP_ENUM_VIS chars_format
@@ -147,9 +155,6 @@ static constexpr uint32_t __pow10_32[] = {
UINT32_C(1000000000),
};
-_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
-_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
-
template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
{
@@ -607,4 +612,6 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_CHARCONV
diff --git a/include/chrono b/include/chrono
index f6a6f4b24343..96759f9860ee 100644
--- a/include/chrono
+++ b/include/chrono
@@ -33,9 +33,9 @@ template <class Rep>
struct duration_values
{
public:
- static constexpr Rep zero();
- static constexpr Rep max();
- static constexpr Rep min();
+ static constexpr Rep zero(); // noexcept in C++20
+ static constexpr Rep max(); // noexcept in C++20
+ static constexpr Rep min(); // noexcept in C++20
};
// duration
@@ -77,22 +77,24 @@ public:
constexpr common_type<duration>::type operator+() const;
constexpr common_type<duration>::type operator-() const;
- constexpr duration& operator++();
- constexpr duration operator++(int);
- constexpr duration& operator--();
- constexpr duration operator--(int);
+ constexpr duration& operator++(); // constexpr in C++17
+ constexpr duration operator++(int); // constexpr in C++17
+ constexpr duration& operator--(); // constexpr in C++17
+ constexpr duration operator--(int); // constexpr in C++17
- constexpr duration& operator+=(const duration& d);
- constexpr duration& operator-=(const duration& d);
+ constexpr duration& operator+=(const duration& d); // constexpr in C++17
+ constexpr duration& operator-=(const duration& d); // constexpr in C++17
- duration& operator*=(const rep& rhs);
- duration& operator/=(const rep& rhs);
+ duration& operator*=(const rep& rhs); // constexpr in C++17
+ duration& operator/=(const rep& rhs); // constexpr in C++17
+ duration& operator%=(const rep& rhs); // constexpr in C++17
+ duration& operator%=(const duration& rhs); // constexpr in C++17
// special values
- static constexpr duration zero();
- static constexpr duration min();
- static constexpr duration max();
+ static constexpr duration zero(); // noexcept in C++20
+ static constexpr duration min(); // noexcept in C++20
+ static constexpr duration max(); // noexcept in C++20
};
typedef duration<long long, nano> nanoseconds;
@@ -127,13 +129,13 @@ public:
// arithmetic
- time_point& operator+=(const duration& d);
- time_point& operator-=(const duration& d);
+ time_point& operator+=(const duration& d); // constexpr in C++17
+ time_point& operator-=(const duration& d); // constexpr in C++17
// special values
- static constexpr time_point min();
- static constexpr time_point max();
+ static constexpr time_point min(); // noexcept in C++20
+ static constexpr time_point max(); // noexcept in C++20
};
} // chrono
@@ -323,7 +325,7 @@ struct clock_time_conversion;
template<class DestClock, class SourceClock, class Duration>
auto clock_cast(const time_point<SourceClock, Duration>& t);
-
+
// 25.8.2, class last_spec // C++20
struct last_spec;
@@ -528,7 +530,7 @@ constexpr year_month_weekday_last
operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
constexpr year_month_weekday_last
operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
-
+
// 25.8.18, civil calendar conventional syntax operators // C++20
constexpr year_month
operator/(const year& y, const month& m) noexcept;
@@ -609,7 +611,7 @@ constexpr year_month_weekday_last
constexpr year_month_weekday_last
operator/(const month_weekday_last& mwdl, const year& y) noexcept;
constexpr year_month_weekday_last
- operator/(const month_weekday_last& mwdl, int y) noexcept;
+ operator/(const month_weekday_last& mwdl, int y) noexcept;
// 25.9, class template time_of_day // C++20
template<class Duration> class time_of_day;
@@ -640,7 +642,7 @@ class ambiguous_local_time;
// 25.10.4, information classes // C++20
struct sys_info;
struct local_info;
-
+
// 25.10.5, class time_zone // C++20
enum class choose {earliest, latest};
class time_zone;
@@ -650,7 +652,7 @@ bool operator<(const time_zone& x, const time_zone& y) noexcept;
bool operator>(const time_zone& x, const time_zone& y) noexcept;
bool operator<=(const time_zone& x, const time_zone& y) noexcept;
bool operator>=(const time_zone& x, const time_zone& y) noexcept;
-
+
// 25.10.6, class template zoned_traits // C++20
template<class T> struct zoned_traits;
@@ -724,7 +726,7 @@ template<class charT, class traits, class Alloc, class Streamable>
template<class charT, class traits, class Alloc, class Streamable>
basic_string<charT, traits, Alloc>
format(const locale& loc, const basic_string<charT, traits, Alloc>& fmt,
- const Streamable& s);
+ const Streamable& s);
// 25.12, parsing // C++20
template<class charT, class traits, class Alloc, class Parsable>
@@ -746,7 +748,8 @@ unspecified
parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp,
basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
-inline constexpr last_spec last{}; // C++20
+// calendrical constants
+inline constexpr last_spec last{}; // C++20
inline constexpr chrono::weekday Sunday{0}; // C++20
inline constexpr chrono::weekday Monday{1}; // C++20
inline constexpr chrono::weekday Tuesday{2}; // C++20
@@ -796,6 +799,7 @@ constexpr chrono::year operator ""y(unsigned lo
#include <type_traits>
#include <ratio>
#include <limits>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -804,6 +808,11 @@ constexpr chrono::year operator ""y(unsigned lo
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
+#ifndef _LIBCPP_CXX03_LANG
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+struct _FilesystemClock;
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -920,9 +929,9 @@ template <class _Rep>
struct _LIBCPP_TEMPLATE_VIS duration_values
{
public:
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);}
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() {return numeric_limits<_Rep>::max();}
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() {return numeric_limits<_Rep>::lowest();}
+ _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
@@ -1015,7 +1024,7 @@ class _LIBCPP_TEMPLATE_VIS duration
typedef ratio<__mul<__n1, __d2, !value>::value,
__mul<__n2, __d1, !value>::value> type;
};
-
+
public:
typedef _Rep rep;
typedef typename _Period::type period;
@@ -1077,9 +1086,9 @@ public:
// special values
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() {return duration(duration_values<rep>::zero());}
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() {return duration(duration_values<rep>::min());}
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() {return duration(duration_values<rep>::max());}
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());}
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());}
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());}
};
typedef duration<long long, nano> nanoseconds;
@@ -1088,7 +1097,12 @@ typedef duration<long long, milli> milliseconds;
typedef duration<long long > seconds;
typedef duration< long, ratio< 60> > minutes;
typedef duration< long, ratio<3600> > hours;
-
+#if _LIBCPP_STD_VER > 17
+typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days;
+typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks;
+typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years;
+typedef duration< int, ratio_divide<years::period, ratio<12>>> months;
+#endif
// Duration ==
template <class _LhsDuration, class _RhsDuration>
@@ -1355,13 +1369,13 @@ public:
// arithmetic
- _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
- _LIBCPP_INLINE_VISIBILITY 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;}
+ _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() {return time_point(duration::min());}
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() {return time_point(duration::max());}
+ _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());}
};
} // chrono
@@ -1571,12 +1585,1158 @@ typedef steady_clock high_resolution_clock;
typedef system_clock high_resolution_clock;
#endif
+#if _LIBCPP_STD_VER > 17
+// [time.clock.file], type file_clock
+using file_clock = _VSTD_FS::_FilesystemClock;
+
+template<class _Duration>
+using file_time = time_point<file_clock, _Duration>;
+
+
+template <class _Duration>
+using sys_time = time_point<system_clock, _Duration>;
+using sys_seconds = sys_time<seconds>;
+using sys_days = sys_time<days>;
+
+struct local_t {};
+template<class Duration>
+using local_time = time_point<local_t, Duration>;
+using local_seconds = local_time<seconds>;
+using local_days = local_time<days>;
+
+
+struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; };
+
+class _LIBCPP_TYPE_VIS day {
+private:
+ unsigned char __d;
+public:
+ day() = default;
+ explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {}
+ inline constexpr day& operator++() noexcept { ++__d; return *this; }
+ inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; }
+ inline constexpr day& operator--() noexcept { --__d; return *this; }
+ inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; }
+ constexpr day& operator+=(const days& __dd) noexcept;
+ constexpr day& operator-=(const days& __dd) noexcept;
+ explicit inline constexpr operator unsigned() const noexcept { return __d; }
+ inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; }
+ };
+
+
+inline constexpr
+bool operator==(const day& __lhs, const day& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
+
+inline constexpr
+bool operator!=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const day& __lhs, const day& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
+
+inline constexpr
+bool operator> (const day& __lhs, const day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const day& __lhs, const day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+inline constexpr
+day operator+ (const day& __lhs, const days& __rhs) noexcept
+{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); }
+
+inline constexpr
+day operator+ (const days& __lhs, const day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+day operator- (const day& __lhs, const days& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+inline constexpr
+days operator-(const day& __lhs, const day& __rhs) noexcept
+{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) -
+ static_cast<int>(static_cast<unsigned>(__rhs))); }
+
+inline constexpr day& day::operator+=(const days& __dd) noexcept
+{ *this = *this + __dd; return *this; }
+
+inline constexpr day& day::operator-=(const days& __dd) noexcept
+{ *this = *this - __dd; return *this; }
+
+
+class _LIBCPP_TYPE_VIS month {
+private:
+ unsigned char __m;
+public:
+ month() = default;
+ explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {}
+ inline constexpr month& operator++() noexcept { ++__m; return *this; }
+ inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; }
+ inline constexpr month& operator--() noexcept { --__m; return *this; }
+ inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; }
+ constexpr month& operator+=(const months& __m1) noexcept;
+ constexpr month& operator-=(const months& __m1) noexcept;
+ explicit inline constexpr operator unsigned() const noexcept { return __m; }
+ inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; }
+};
+
+
+inline constexpr
+bool operator==(const month& __lhs, const month& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
+
+inline constexpr
+bool operator!=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const month& __lhs, const month& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
+
+inline constexpr
+bool operator> (const month& __lhs, const month& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__rhs < __lhs); }
+
+inline constexpr
+bool operator>=(const month& __lhs, const month& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+inline constexpr
+month operator+ (const month& __lhs, const months& __rhs) noexcept
+{
+ auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1);
+ auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12;
+ return month{static_cast<unsigned>(__mu - __yr * 12 + 1)};
+}
+
+inline constexpr
+month operator+ (const months& __lhs, const month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+month operator- (const month& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+inline constexpr
+months operator-(const month& __lhs, const month& __rhs) noexcept
+{
+ auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
+ return months(__dm <= 11 ? __dm : __dm + 12);
+}
+
+inline constexpr month& month::operator+=(const months& __dm) noexcept
+{ *this = *this + __dm; return *this; }
+
+inline constexpr month& month::operator-=(const months& __dm) noexcept
+{ *this = *this - __dm; return *this; }
+
+
+class _LIBCPP_TYPE_VIS year {
+private:
+ short __y;
+public:
+ year() = default;
+ explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {}
+
+ inline constexpr year& operator++() noexcept { ++__y; return *this; };
+ inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; };
+ inline constexpr year& operator--() noexcept { --__y; return *this; };
+ inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; };
+ constexpr year& operator+=(const years& __dy) noexcept;
+ constexpr year& operator-=(const years& __dy) noexcept;
+ inline constexpr year operator+() const noexcept { return *this; }
+ inline constexpr year operator-() const noexcept { return year{-__y}; };
+
+ inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); }
+ explicit inline constexpr operator int() const noexcept { return __y; }
+ constexpr bool ok() const noexcept;
+ static inline constexpr year min() noexcept { return year{-32767}; }
+ static inline constexpr year max() noexcept { return year{ 32767}; }
+};
+
+
+inline constexpr
+bool operator==(const year& __lhs, const year& __rhs) noexcept
+{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); }
+
+inline constexpr
+bool operator!=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const year& __lhs, const year& __rhs) noexcept
+{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); }
+
+inline constexpr
+bool operator> (const year& __lhs, const year& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__rhs < __lhs); }
+
+inline constexpr
+bool operator>=(const year& __lhs, const year& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+inline constexpr
+year operator+ (const year& __lhs, const years& __rhs) noexcept
+{ return year(static_cast<int>(__lhs) + __rhs.count()); }
+
+inline constexpr
+year operator+ (const years& __lhs, const year& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year operator- (const year& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+inline constexpr
+years operator-(const year& __lhs, const year& __rhs) noexcept
+{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; }
+
+
+inline constexpr year& year::operator+=(const years& __dy) noexcept
+{ *this = *this + __dy; return *this; }
+
+inline constexpr year& year::operator-=(const years& __dy) noexcept
+{ *this = *this - __dy; return *this; }
+
+inline constexpr bool year::ok() const noexcept
+{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); }
+
+class _LIBCPP_TYPE_VIS weekday_indexed;
+class _LIBCPP_TYPE_VIS weekday_last;
+
+class _LIBCPP_TYPE_VIS weekday {
+private:
+ unsigned char __wd;
+public:
+ weekday() = default;
+ inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__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 explicit constexpr operator unsigned() const noexcept { return __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;
+
+ static constexpr unsigned char __weekday_from_days(int __days) noexcept;
+};
+
+
+// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days
+inline constexpr
+unsigned char weekday::__weekday_from_days(int __days) noexcept
+{
+ return static_cast<unsigned char>(
+ static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6)
+ );
+}
+
+inline constexpr
+bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); }
+
+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 static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); }
+
+inline constexpr
+bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept
+{
+ auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + __rhs.count();
+ auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7;
+ return weekday{static_cast<unsigned>(__mu - __yr * 7)};
+}
+
+constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept
+{
+ const int __wdu = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs);
+ 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 _LIBCPP_TYPE_VIS weekday_indexed {
+private:
+ _VSTD::chrono::weekday __wd;
+ unsigned char __idx;
+public:
+ weekday_indexed() = default;
+ inline constexpr weekday_indexed(const _VSTD::chrono::weekday& __wdval, unsigned __idxval) noexcept
+ : __wd{__wdval}, __idx(__idxval) {}
+ inline constexpr _VSTD::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 _LIBCPP_TYPE_VIS weekday_last {
+private:
+ _VSTD::chrono::weekday __wd;
+public:
+ explicit constexpr weekday_last(const _VSTD::chrono::weekday& __val) noexcept
+ : __wd{__val} {}
+ constexpr _VSTD::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 _LIBCPP_TYPE_VIS month_day {
+private:
+ chrono::month __m;
+ chrono::day __d;
+public:
+ month_day() = default;
+ constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept
+ : __m{__mval}, __d{__dval} {}
+ inline constexpr chrono::month month() const noexcept { return __m; }
+ inline constexpr chrono::day day() const noexcept { return __d; }
+ constexpr bool ok() const noexcept;
+};
+
+inline constexpr
+bool month_day::ok() const noexcept
+{
+ if (!__m.ok()) return false;
+ const unsigned __dval = static_cast<unsigned>(__d);
+ if (__dval < 1 || __dval > 31) return false;
+ if (__dval <= 29) return true;
+// Now we've got either 30 or 31
+ const unsigned __mval = static_cast<unsigned>(__m);
+ if (__mval == 2) return false;
+ if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11)
+ return __dval == 30;
+ return true;
+}
+
+inline constexpr
+bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
+
+inline constexpr
+bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+month_day operator/(const month& __lhs, const day& __rhs) noexcept
+{ return month_day{__lhs, __rhs}; }
+
+constexpr
+month_day operator/(const day& __lhs, const month& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+inline constexpr
+month_day operator/(const month& __lhs, int __rhs) noexcept
+{ return __lhs / day(__rhs); }
+
+constexpr
+month_day operator/(int __lhs, const day& __rhs) noexcept
+{ return month(__lhs) / __rhs; }
+
+constexpr
+month_day operator/(const day& __lhs, int __rhs) noexcept
+{ return month(__rhs) / __lhs; }
+
+
+inline constexpr
+bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); }
+
+inline constexpr
+bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+
+
+class _LIBCPP_TYPE_VIS 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 _LIBCPP_TYPE_VIS month_weekday {
+private:
+ chrono::month __m;
+ chrono::weekday_indexed __wdi;
+public:
+ month_weekday() = default;
+ 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 _LIBCPP_TYPE_VIS 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 _LIBCPP_TYPE_VIS year_month {
+ chrono::year __y;
+ chrono::month __m;
+public:
+ year_month() = default;
+ constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept
+ : __y{__yval}, __m{__mval} {}
+ inline constexpr chrono::year year() const noexcept { return __y; }
+ inline constexpr chrono::month month() const noexcept { return __m; }
+ inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; }
+ inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; }
+ inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; }
+ inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; }
+ inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); }
+};
+
+inline constexpr
+year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; }
+
+inline constexpr
+year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; }
+
+inline constexpr
+bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); }
+
+inline constexpr
+bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); }
+
+inline constexpr
+bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept
+{
+ int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count();
+ const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12;
+ __dmi = __dmi - __dy * 12 + 1;
+ return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi));
+}
+
+constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept
+{ return (__lhs.year() + __rhs) / __lhs.month(); }
+
+constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept
+{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); }
+
+constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+class year_month_day_last;
+
+class _LIBCPP_TYPE_VIS 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(std::numeric_limits<unsigned>::digits >= 18, "");
+ static_assert(std::numeric_limits<int>::digits >= 20 , "");
+ const int __z = __d.count() + 719468;
+ const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;
+ const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]
+ const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399]
+ const int __yr = static_cast<int>(__yoe) + __era * 400;
+ const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365]
+ const unsigned __mp = (5 * __doy + 2)/153; // [0, 11]
+ const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31]
+ const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]
+ return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};
+}
+
+// https://howardhinnant.github.io/date_algorithms.html#days_from_civil
+inline constexpr days year_month_day::__to_days() const noexcept
+{
+ static_assert(std::numeric_limits<unsigned>::digits >= 18, "");
+ static_assert(std::numeric_limits<int>::digits >= 20 , "");
+
+ const int __yr = static_cast<int>(__y) - (__m <= February);
+ const unsigned __mth = static_cast<unsigned>(__m);
+ const unsigned __dy = static_cast<unsigned>(__d);
+
+ const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;
+ const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]
+ const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365]
+ const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096]
+ return days{__era * 146097 + static_cast<int>(__doe) - 719468};
+}
+
+inline constexpr
+bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); }
+
+inline constexpr
+bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{
+ if (__lhs.year() < __rhs.year()) return true;
+ if (__lhs.year() > __rhs.year()) return false;
+ if (__lhs.month() < __rhs.month()) return true;
+ if (__lhs.month() > __rhs.month()) return false;
+ return __lhs.day() < __rhs.day();
+}
+
+inline constexpr
+bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+inline constexpr
+year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept
+{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; }
+
+inline constexpr
+year_month_day operator/(const year_month& __lhs, int __rhs) noexcept
+{ return __lhs / day(__rhs); }
+
+inline constexpr
+year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept
+{ return __lhs / __rhs.month() / __rhs.day(); }
+
+inline constexpr
+year_month_day operator/(int __lhs, const month_day& __rhs) noexcept
+{ return year(__lhs) / __rhs; }
+
+inline constexpr
+year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+inline constexpr
+year_month_day operator/(const month_day& __lhs, int __rhs) noexcept
+{ return year(__rhs) / __lhs; }
+
+
+inline constexpr
+year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); }
+
+inline constexpr
+year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+inline constexpr
+year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept
+{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); }
+
+inline constexpr
+year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept
+{ return __lhs + -__rhs; }
+
+inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+class _LIBCPP_TYPE_VIS 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() ?
+ __d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
+}
+
+inline constexpr
+bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); }
+
+inline constexpr
+bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{
+ if (__lhs.year() < __rhs.year()) return true;
+ if (__lhs.year() > __rhs.year()) return false;
+ return __lhs.month_day_last() < __rhs.month_day_last();
+}
+
+inline constexpr
+bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs < __lhs; }
+
+inline constexpr
+bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__rhs < __lhs);}
+
+inline constexpr
+bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept
+{ return !(__lhs < __rhs); }
+
+inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept
+{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; }
+
+inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept
+{ return year_month_day_last{__lhs, __rhs}; }
+
+inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept
+{ return year_month_day_last{year{__lhs}, __rhs}; }
+
+inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept
+{ return year{__rhs} / __lhs; }
+
+
+inline constexpr
+year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year() / __lhs.month() + __rhs) / last; }
+
+inline constexpr
+year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+inline constexpr
+year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept
+{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; }
+
+inline constexpr
+year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
+ : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {}
+
+inline constexpr bool year_month_day::ok() const noexcept
+{
+ if (!__y.ok() || !__m.ok()) return false;
+ return chrono::day{1} <= __d && __d <= (__y / __m / last).day();
+}
+
+class _LIBCPP_TYPE_VIS 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;
+ // TODO: make sure it's a valid date
+ return true;
+ }
+
+ static constexpr year_month_weekday __from_days(days __d) noexcept;
+ constexpr days __to_days() const noexcept;
+};
+
+inline constexpr
+year_month_weekday year_month_weekday::__from_days(days __d) noexcept
+{
+ const sys_days __sysd{__d};
+ const chrono::weekday __wd = chrono::weekday(__sysd);
+ const year_month_day __ymd = year_month_day(__sysd);
+ return year_month_weekday{__ymd.year(), __ymd.month(),
+ __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]};
+}
+
+inline constexpr
+days year_month_weekday::__to_days() const noexcept
+{
+ const sys_days __sysd = sys_days(__y/__m/1);
+ return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7}))
+ .time_since_epoch();
+}
+
+inline constexpr
+bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); }
+
+inline constexpr
+bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept
+{ return !(__lhs == __rhs); }
+
+inline constexpr
+year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept
+{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; }
+
+inline constexpr
+year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept
+{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; }
+
+inline constexpr
+year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept
+{ return year(__lhs) / __rhs; }
+
+inline constexpr
+year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept
+{ return __rhs / __lhs; }
+
+inline constexpr
+year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept
+{ return year(__rhs) / __lhs; }
+
+
+inline constexpr
+year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept
+{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); }
+
+inline constexpr
+year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+inline constexpr
+year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept
+{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; }
+
+inline constexpr
+year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept
+{ return __rhs + __lhs; }
+
+inline constexpr
+year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept
+{ return __lhs + (-__rhs); }
+
+
+inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; }
+inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; }
+inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; }
+inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; }
+
+class _LIBCPP_TYPE_VIS 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; }
+
+#endif // _LIBCPP_STD_VER > 17
} // chrono
#if _LIBCPP_STD_VER > 11
// Suffixes for duration literals [time.duration.literals]
inline namespace literals
-{
+{
inline namespace chrono_literals
{
@@ -1633,7 +2793,7 @@ inline namespace literals
{
return chrono::duration<long double, micro> (__us);
}
-
+
constexpr chrono::nanoseconds operator""ns(unsigned long long __ns)
{
@@ -1645,6 +2805,17 @@ inline namespace literals
return chrono::duration<long double, nano> (__ns);
}
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS)
+ constexpr chrono::day operator ""d(unsigned long long __d) noexcept
+ {
+ return chrono::day(static_cast<unsigned>(__d));
+ }
+
+ constexpr chrono::year operator ""y(unsigned long long __y) noexcept
+ {
+ return chrono::year(static_cast<int>(__y));
+ }
+#endif
}}
namespace chrono { // hoist the literals into namespace std::chrono
@@ -1655,6 +2826,40 @@ namespace chrono { // hoist the literals into namespace std::chrono
_LIBCPP_END_NAMESPACE_STD
+#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<rep, period> duration;
+ typedef chrono::time_point<_FilesystemClock> time_point;
+
+ static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
+
+ _LIBCPP_FUNC_VIS static time_point now() noexcept;
+
+ _LIBCPP_INLINE_VISIBILITY
+ static time_t to_time_t(const time_point& __t) noexcept {
+ typedef chrono::duration<rep> __secs;
+ return time_t(
+ chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ static time_point from_time_t(time_t __t) noexcept {
+ typedef chrono::duration<rep> __secs;
+ return time_point(__secs(__t));
+ }
+};
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+#endif // !_LIBCPP_CXX03_LANG
+
_LIBCPP_POP_MACROS
#endif // _LIBCPP_CHRONO
diff --git a/include/cmath b/include/cmath
index ffb1c46c7b68..f5f62adcfb8d 100644
--- a/include/cmath
+++ b/include/cmath
@@ -303,6 +303,7 @@ long double truncl(long double x);
#include <__config>
#include <math.h>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
diff --git a/include/complex b/include/complex
index d692ee319204..8cf6a946d711 100644
--- a/include/complex
+++ b/include/complex
@@ -245,6 +245,7 @@ template<class T, class charT, class traits>
#include <stdexcept>
#include <cmath>
#include <sstream>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
diff --git a/include/cstddef b/include/cstddef
index adeefdac9be6..b4c42b19ddb2 100644
--- a/include/cstddef
+++ b/include/cstddef
@@ -35,6 +35,7 @@ Types:
*/
#include <__config>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -50,7 +51,7 @@ using ::ptrdiff_t;
using ::size_t;
#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \
- defined(__DEFINED_max_align_t)
+ defined(__DEFINED_max_align_t) || defined(__NetBSD__)
// Re-use the compiler's <stddef.h> max_align_t where possible.
using ::max_align_t;
#else
@@ -66,10 +67,10 @@ enum class byte : unsigned char {};
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{
- return static_cast<byte>(
- static_cast<unsigned char>(
- static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs)
- ));
+ return static_cast<byte>(
+ static_cast<unsigned char>(
+ static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs)
+ ));
}
constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
@@ -77,10 +78,10 @@ constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
constexpr byte operator& (byte __lhs, byte __rhs) noexcept
{
- return static_cast<byte>(
- static_cast<unsigned char>(
- static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs)
- ));
+ return static_cast<byte>(
+ static_cast<unsigned char>(
+ static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs)
+ ));
}
constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
@@ -88,13 +89,13 @@ constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
constexpr byte operator^ (byte __lhs, byte __rhs) noexcept
{
- return static_cast<byte>(
- static_cast<unsigned char>(
- static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs)
- ));
+ return static_cast<byte>(
+ static_cast<unsigned char>(
+ static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs)
+ ));
}
-constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
+constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = __lhs ^ __rhs; }
constexpr byte operator~ (byte __b) noexcept
diff --git a/include/cstdlib b/include/cstdlib
index 78c428403c37..00c604e67623 100644
--- a/include/cstdlib
+++ b/include/cstdlib
@@ -151,11 +151,11 @@ using ::mbtowc;
using ::wctomb;
using ::mbstowcs;
using ::wcstombs;
-#ifdef _LIBCPP_HAS_QUICK_EXIT
+#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
using ::at_quick_exit;
using ::quick_exit;
#endif
-#ifdef _LIBCPP_HAS_C11_FEATURES
+#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
using ::aligned_alloc;
#endif
diff --git a/include/ctime b/include/ctime
index 81cf11a466c2..8264fe33b964 100644
--- a/include/ctime
+++ b/include/ctime
@@ -73,7 +73,7 @@ using ::gmtime;
using ::localtime;
#endif
using ::strftime;
-#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
+#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET)
using ::timespec_get;
#endif
diff --git a/include/deque b/include/deque
index bfbd3a5ef543..6f7d04be52be 100644
--- a/include/deque
+++ b/include/deque
@@ -150,6 +150,11 @@ template <class T, class Allocator>
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class T, class Allocator, class U>
+ void erase(deque<T, Allocator>& c, const U& value); // C++20
+template <class T, class Allocator, class Predicate>
+ void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -161,6 +166,7 @@ template <class T, class Allocator>
#include <iterator>
#include <algorithm>
#include <stdexcept>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -986,7 +992,7 @@ public:
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT;
#else
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
#endif
protected:
@@ -1155,7 +1161,7 @@ __deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
#else
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
{
@@ -2341,7 +2347,7 @@ deque<_Tp, _Allocator>::__add_front_capacity()
_Dp(__a, __base::__block_size));
__buf.push_back(__hold.get());
__hold.release();
-
+
for (typename __base::__map_pointer __i = __base::__map_.begin();
__i != __base::__map_.end(); ++__i)
__buf.push_back(*__i);
@@ -2603,6 +2609,7 @@ template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::pop_back()
{
+ _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque");
allocator_type& __a = __base::__alloc();
size_type __p = __base::size() + __base::__start_ - 1;
__alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
@@ -2853,7 +2860,7 @@ deque<_Tp, _Allocator>::swap(deque& __c)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
#else
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
{
@@ -2926,6 +2933,19 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp, class _Allocator, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
+{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
+
+template <class _Tp, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
+{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
+#endif
+
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/include/exception b/include/exception
index b517486b5a8e..fdd83d10c3da 100644
--- a/include/exception
+++ b/include/exception
@@ -81,6 +81,7 @@ template <class E> void rethrow_if_nested(const E& e);
#include <cstddef>
#include <cstdlib>
#include <type_traits>
+#include <version>
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#include <vcruntime_exception.h>
@@ -163,7 +164,7 @@ public:
};
template<class _Ep>
-exception_ptr
+_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -222,7 +223,7 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
template <class _E> void *__GetExceptionInfo(_E);
template<class _Ep>
-exception_ptr
+_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
diff --git a/include/experimental/any b/include/experimental/any
index 1dcdd0f25ec3..d9c95342589f 100644
--- a/include/experimental/any
+++ b/include/experimental/any
@@ -1,11 +1,21 @@
// -*- C++ -*-
-//===------------------------------ any -----------------------------------===//
+//===------------------------------- any ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_ANY
+#define _LIBCPP_EXPERIMENTAL_ANY
-#error "<experimental/any> has been removed. Use <any> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/any> has been removed. Use <any> instead.")
+#else
+# warning "<experimental/any> has been removed. Use <any> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_ANY
diff --git a/include/experimental/chrono b/include/experimental/chrono
index 591cf7160c13..30c7e4a9d5ac 100644
--- a/include/experimental/chrono
+++ b/include/experimental/chrono
@@ -1,11 +1,21 @@
// -*- C++ -*-
-//===------------------------------ chrono ---------------------------------===//
+//===---------------------------- chrono ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_CHRONO
+#define _LIBCPP_EXPERIMENTAL_CHRONO
-#error "<experimental/chrono> has been removed. Use <chrono> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/chrono> has been removed. Use <chrono> instead.")
+#else
+# warning "<experimental/chrono> has been removed. Use <chrono> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_CHRONO
diff --git a/include/experimental/coroutine b/include/experimental/coroutine
index 1eb224a535a1..7cb39b81b48f 100644
--- a/include/experimental/coroutine
+++ b/include/experimental/coroutine
@@ -214,7 +214,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
- __builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
+ __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
public:
@@ -254,7 +254,7 @@ public:
coroutine_handle __tmp;
__tmp.__handle_ = __builtin_coro_promise(
_VSTD::addressof(const_cast<_RawPromise&>(__promise)),
- __alignof(_Promise), true);
+ _LIBCPP_ALIGNOF(_Promise), true);
return __tmp;
}
};
@@ -272,7 +272,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
- __builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
+ __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
_LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
diff --git a/include/experimental/dynarray b/include/experimental/dynarray
deleted file mode 100644
index a60c87c3f970..000000000000
--- a/include/experimental/dynarray
+++ /dev/null
@@ -1,305 +0,0 @@
-// -*- C++ -*-
-//===-------------------------- dynarray ----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP_DYNARRAY
-#define _LIBCPP_DYNARRAY
-
-/*
- dynarray synopsis
-
-namespace std { namespace experimental {
-
-template< typename T >
-class dynarray
-{
- // types:
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef implementation-defined iterator;
- typedef implementation-defined const_iterator;
- typedef reverse_iterator<iterator> reverse_iterator;
- typedef reverse_iterator<const_iterator> const_reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
-
-public:
- // construct/copy/destroy:
- explicit dynarray(size_type c);
- dynarray(size_type c, const T& v);
- dynarray(const dynarray& d);
- dynarray(initializer_list<T>);
-
- template <class Alloc>
- dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
- template <class Alloc>
- dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
- template <class Alloc>
- dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
- template <class Alloc>
- dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
- dynarray& operator=(const dynarray&) = delete;
- ~dynarray();
-
- // iterators:
- iterator begin() noexcept;
- const_iterator begin() const noexcept;
- const_iterator cbegin() const noexcept;
- iterator end() noexcept;
- const_iterator end() const noexcept;
- const_iterator cend() const noexcept;
-
- reverse_iterator rbegin() noexcept;
- const_reverse_iterator rbegin() const noexcept;
- const_reverse_iterator crbegin() const noexcept;
- reverse_iterator rend() noexcept;
- const_reverse_iterator rend() const noexcept;
- const_reverse_iterator crend() const noexcept;
-
- // capacity:
- size_type size() const noexcept;
- size_type max_size() const noexcept;
- bool empty() const noexcept;
-
- // element access:
- reference operator[](size_type n);
- const_reference operator[](size_type n) const;
-
- reference front();
- const_reference front() const;
- reference back();
- const_reference back() const;
-
- const_reference at(size_type n) const;
- reference at(size_type n);
-
- // data access:
- T* data() noexcept;
- const T* data() const noexcept;
-
- // mutating member functions:
- void fill(const T& v);
-};
-
-}} // std::experimental
-
-*/
-#include <__config>
-#if _LIBCPP_STD_VER > 11
-
-#include <__functional_base>
-#include <iterator>
-#include <stdexcept>
-#include <initializer_list>
-#include <new>
-#include <algorithm>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-namespace std { namespace experimental { inline namespace __array_extensions_v1 {
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray
-{
-public:
- // types:
- typedef dynarray __self;
- typedef _Tp value_type;
- typedef value_type& reference;
- typedef const value_type& const_reference;
- typedef value_type* iterator;
- typedef const value_type* const_iterator;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-private:
- size_t __size_;
- value_type * __base_;
- _LIBCPP_INLINE_VISIBILITY dynarray () noexcept : __size_(0), __base_(nullptr) {}
-
- static inline _LIBCPP_INLINE_VISIBILITY
- value_type* __allocate(size_t __count) {
- if (numeric_limits<size_t>::max() / sizeof (value_type) <= __count)
- __throw_bad_array_length();
-
- return static_cast<value_type *>(
- _VSTD::__libcpp_allocate(sizeof(value_type) * __count, __alignof(value_type)));
- }
-
- static inline _LIBCPP_INLINE_VISIBILITY
- void __deallocate_value(value_type* __ptr ) noexcept {
- _VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), __alignof(value_type));
- }
-
-public:
-
- _LIBCPP_INLINE_VISIBILITY
- explicit dynarray(size_type __c);
- _LIBCPP_INLINE_VISIBILITY
- dynarray(size_type __c, const value_type& __v);
- _LIBCPP_INLINE_VISIBILITY
- dynarray(const dynarray& __d);
- _LIBCPP_INLINE_VISIBILITY
- dynarray(initializer_list<value_type>);
-
-// We're not implementing these right now.
-// Updated with the resolution of LWG issue #2255
-// template <typename _Alloc>
-// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c);
-// template <typename _Alloc>
-// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v);
-// template <typename _Alloc>
-// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d);
-// template <typename _Alloc>
-// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>);
-
- dynarray& operator=(const dynarray&) = delete;
- _LIBCPP_INLINE_VISIBILITY
- ~dynarray();
-
- // iterators:
- inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); }
- inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); }
- inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
- inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); }
- inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); }
- inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); }
-
- inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
- inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
- inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
- inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
- inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
- inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
-
- // capacity:
- inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; }
- inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
- inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; }
-
- // element access:
- inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; }
- inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
-
- inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; }
- inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
- inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; }
- inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; }
-
- inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
- inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n);
-
- // data access:
- inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; }
- inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
-
- // mutating member functions:
- inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
-};
-
-template <class _Tp>
-inline
-dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
-{
- __base_ = __allocate (__c);
- value_type *__data = data ();
- for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
- ::new (__data) value_type;
-}
-
-template <class _Tp>
-inline
-dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
-{
- __base_ = __allocate (__c);
- value_type *__data = data ();
- for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
- ::new (__data) value_type (__v);
-}
-
-template <class _Tp>
-inline
-dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
-{
- size_t sz = __il.size();
- __base_ = __allocate (sz);
- value_type *__data = data ();
- auto src = __il.begin();
- for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
- ::new (__data) value_type (*src);
-}
-
-template <class _Tp>
-inline
-dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
-{
- size_t sz = __d.size();
- __base_ = __allocate (sz);
- value_type *__data = data ();
- auto src = __d.begin();
- for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
- ::new (__data) value_type (*src);
-}
-
-template <class _Tp>
-inline
-dynarray<_Tp>::~dynarray()
-{
- value_type *__data = data () + __size_;
- for ( size_t i = 0; i < __size_; ++i )
- (--__data)->value_type::~value_type();
- __deallocate_value( __base_ );
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename dynarray<_Tp>::reference
-dynarray<_Tp>::at(size_type __n)
-{
- if (__n >= __size_)
- __throw_out_of_range("dynarray::at");
-
- return data()[__n];
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename dynarray<_Tp>::const_reference
-dynarray<_Tp>::at(size_type __n) const
-{
- if (__n >= __size_)
- __throw_out_of_range("dynarray::at");
-
- return data()[__n];
-}
-
-}}}
-
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Tp, class _Alloc>
-struct _LIBCPP_TEMPLATE_VIS uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // if _LIBCPP_STD_VER > 11
-#endif // _LIBCPP_DYNARRAY
diff --git a/include/experimental/memory_resource b/include/experimental/memory_resource
index 221ce5b8eacc..83781d462034 100644
--- a/include/experimental/memory_resource
+++ b/include/experimental/memory_resource
@@ -98,7 +98,7 @@ size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
// 8.5, memory.resource
class _LIBCPP_TYPE_VIS memory_resource
{
- static const size_t __max_align = alignof(max_align_t);
+ static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
// 8.5.2, memory.resource.public
public:
@@ -190,7 +190,7 @@ public:
" 'n' exceeds maximum supported size");
}
return static_cast<_ValueType*>(
- __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType))
+ __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType))
);
}
@@ -198,7 +198,7 @@ public:
void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
_LIBCPP_ASSERT(__n <= __max_size(),
"deallocate called for size which exceeds max_size()");
- __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
+ __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
}
template <class _Tp, class ..._Ts>
@@ -345,7 +345,7 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
&& is_same<typename _CTraits::pointer, char*>::value
&& is_same<typename _CTraits::void_pointer, void*>::value, "");
- static const size_t _MaxAlign = alignof(max_align_t);
+ static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t);
using _Alloc = typename _CTraits::template rebind_alloc<
typename aligned_storage<_MaxAlign, _MaxAlign>::type
diff --git a/include/experimental/numeric b/include/experimental/numeric
index 14a664011b56..19c65313f0f2 100644
--- a/include/experimental/numeric
+++ b/include/experimental/numeric
@@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC
+#define _LIBCPP_EXPERIMENTAL_NUMERIC
-#error "<experimental/numeric> has been removed. Use <numeric> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/numeric> has been removed. Use <numeric> instead.")
+#else
+# warning "<experimental/numeric> has been removed. Use <numeric> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_NUMERIC
diff --git a/include/experimental/optional b/include/experimental/optional
index d68cefdf6c1d..6eb4a2618d2c 100644
--- a/include/experimental/optional
+++ b/include/experimental/optional
@@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL
+#define _LIBCPP_EXPERIMENTAL_OPTIONAL
-#error "<experimental/optional> has been removed. Use <optional> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/optional> has been removed. Use <optional> instead.")
+#else
+# warning "<experimental/optional> has been removed. Use <optional> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL
diff --git a/include/experimental/ratio b/include/experimental/ratio
index 9c2bf2e4624e..52c12004dba0 100644
--- a/include/experimental/ratio
+++ b/include/experimental/ratio
@@ -1,11 +1,21 @@
// -*- C++ -*-
-//===------------------------------ ratio ---------------------------------===//
+//===----------------------------- ratio ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_RATIO
+#define _LIBCPP_EXPERIMENTAL_RATIO
-#error "<experimental/ratio> has been removed. Use <ratio> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/ratio> has been removed. Use <ratio> instead.")
+#else
+# warning "<experimental/ratio> has been removed. Use <ratio> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_RATIO
diff --git a/include/experimental/string_view b/include/experimental/string_view
index f13bff54d531..100bdfe72735 100644
--- a/include/experimental/string_view
+++ b/include/experimental/string_view
@@ -3,9 +3,19 @@
//
// The LLVM Compiler Infrastructure
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_STRING_VIEW
+#define _LIBCPP_EXPERIMENTAL_STRING_VIEW
-#error "<experimental/string_view> has been removed. Use <string_view> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/string_view> has been removed. Use <string_view> instead.")
+#else
+# warning "<experimental/string_view> has been removed. Use <string_view> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_STRING_VIEW
diff --git a/include/experimental/system_error b/include/experimental/system_error
index 7937357fa141..1cf84ee01251 100644
--- a/include/experimental/system_error
+++ b/include/experimental/system_error
@@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR
+#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR
-#error "<experimental/system_error> has been removed. Use <system_error> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/system_error> has been removed. Use <system_error> instead.")
+#else
+# warning "<experimental/system_error> has been removed. Use <system_error> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR
diff --git a/include/experimental/tuple b/include/experimental/tuple
index 1f37a6293bac..6d71bb559b02 100644
--- a/include/experimental/tuple
+++ b/include/experimental/tuple
@@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_EXPERIMENTAL_TUPLE
+#define _LIBCPP_EXPERIMENTAL_TUPLE
-#error "<experimental/tuple> has been removed. Use <tuple> instead."
+#include <__config>
+
+#ifdef _LIBCPP_WARNING
+_LIBCPP_WARNING("<experimental/tuple> has been removed. Use <tuple> instead.")
+#else
+# warning "<experimental/tuple> has been removed. Use <tuple> instead."
+#endif
+
+#endif // _LIBCPP_EXPERIMENTAL_TUPLE
diff --git a/include/filesystem b/include/filesystem
index aa1d71800725..af713a063587 100644
--- a/include/filesystem
+++ b/include/filesystem
@@ -244,6 +244,7 @@
#include <utility>
#include <iomanip> // for quoted
#include <string_view>
+#include <version>
#include <__debug>
@@ -256,42 +257,8 @@ _LIBCPP_PUSH_MACROS
#ifndef _LIBCPP_CXX03_LANG
-#if _LIBCPP_STD_VER >= 17
-#define __cpp_lib_filesystem 201703
-#endif
-
_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<rep, period> duration;
- typedef chrono::time_point<_FilesystemClock> time_point;
-
- static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
-
- _LIBCPP_FUNC_VIS static time_point now() noexcept;
-
- _LIBCPP_INLINE_VISIBILITY
- static time_t to_time_t(const time_point& __t) noexcept {
- typedef chrono::duration<rep> __secs;
- return time_t(
- chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
- }
-
- _LIBCPP_INLINE_VISIBILITY
- static time_point from_time_t(time_t __t) noexcept {
- typedef chrono::duration<rep> __secs;
- return time_point(__secs(__t));
- }
-};
-
typedef chrono::time_point<_FilesystemClock> file_time_type;
struct _LIBCPP_TYPE_VIS space_info {
@@ -590,7 +557,7 @@ template <class _ECharT>
typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
__is_separator(_ECharT __e) {
return __e == _ECharT('/');
-};
+}
struct _NullSentinal {};
@@ -1184,6 +1151,31 @@ public:
return __is;
}
+ friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) == 0;
+ }
+ friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) != 0;
+ }
+ friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) < 0;
+ }
+ friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) <= 0;
+ }
+ friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) > 0;
+ }
+ friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
+ return __lhs.compare(__rhs) >= 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 {
@@ -1200,43 +1192,6 @@ inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
_LIBCPP_FUNC_VIS
size_t hash_value(const path& __p) noexcept;
-inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) == 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) != 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) < 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) <= 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) > 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs,
- const path& __rhs) noexcept {
- return __lhs.compare(__rhs) >= 0;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
- const path& __rhs) {
- path __result(__lhs);
- __result /= __rhs;
- return __result;
-}
-
template <class _Source>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_pathable<_Source>::value, path>::type
diff --git a/include/forward_list b/include/forward_list
index 571afdc925b0..b506acd1ff20 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -167,6 +167,11 @@ template <class T, class Allocator>
void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class T, class Allocator, class U>
+ void erase(forward_list<T, Allocator>& c, const U& value); // C++20
+template <class T, class Allocator, class Predicate>
+ void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -177,6 +182,7 @@ template <class T, class Allocator>
#include <limits>
#include <iterator>
#include <algorithm>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -1743,6 +1749,18 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
+{ __c.remove_if(__pred); }
+
+template <class _Tp, class _Allocator, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
+{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
+#endif
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/include/fstream b/include/fstream
index 332b4747c1af..711e484e2dcf 100644
--- a/include/fstream
+++ b/include/fstream
@@ -702,6 +702,7 @@ basic_filebuf<_CharT, _Traits>::close()
__file_ = 0;
else
__rt = 0;
+ setbuf(0, 0);
}
return __rt;
}
diff --git a/include/functional b/include/functional
index 6b70f731e1cc..95491879b0c7 100644
--- a/include/functional
+++ b/include/functional
@@ -68,6 +68,11 @@ template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
template <class T> void cref(const T&& t) = delete;
template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
+template <class T> struct unwrap_reference; // since C++20
+template <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { }; // since C++20
+template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
+template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
+
template <class T> // <class T=void> in C++14
struct plus : binary_function<T, T, T>
{
@@ -183,7 +188,7 @@ struct bit_xor : unary_function<T, bool>
};
template <class Predicate>
-class unary_negate
+class unary_negate // deprecated in C++17
: public unary_function<typename Predicate::argument_type, bool>
{
public:
@@ -191,10 +196,11 @@ public:
bool operator()(const typename Predicate::argument_type& x) const;
};
-template <class Predicate> unary_negate<Predicate> not1(const Predicate& pred);
+template <class Predicate> // deprecated in C++17
+unary_negate<Predicate> not1(const Predicate& pred);
template <class Predicate>
-class binary_negate
+class binary_negate // deprecated in C++17
: public binary_function<typename Predicate::first_argument_type,
typename Predicate::second_argument_type,
bool>
@@ -205,7 +211,8 @@ public:
const typename Predicate::second_argument_type& y) const;
};
-template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred);
+template <class Predicate> // deprecated in C++17
+binary_negate<Predicate> not2(const Predicate& pred);
template <class F> unspecified not_fn(F&& f); // C++17
@@ -487,6 +494,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
#include <memory>
#include <tuple>
#include <utility>
+#include <version>
#include <__functional_base>
@@ -980,7 +988,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void>
#endif
template <class _Predicate>
-class _LIBCPP_TEMPLATE_VIS unary_negate
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
: public unary_function<typename _Predicate::argument_type, bool>
{
_Predicate __pred_;
@@ -994,19 +1002,19 @@ public:
};
template <class _Predicate>
-inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
unary_negate<_Predicate>
not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
template <class _Predicate>
-class _LIBCPP_TEMPLATE_VIS binary_negate
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
: public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type,
bool>
{
_Predicate __pred_;
public:
- _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
+ _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
@@ -1016,13 +1024,13 @@ public:
};
template <class _Predicate>
-inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
binary_negate<_Predicate>
not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
template <class __Operation>
-class _LIBCPP_TEMPLATE_VIS binder1st
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
: public unary_function<typename __Operation::second_argument_type,
typename __Operation::result_type>
{
@@ -1042,13 +1050,13 @@ public:
};
template <class __Operation, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
binder1st<__Operation>
bind1st(const __Operation& __op, const _Tp& __x)
{return binder1st<__Operation>(__op, __x);}
template <class __Operation>
-class _LIBCPP_TEMPLATE_VIS binder2nd
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
: public unary_function<typename __Operation::first_argument_type,
typename __Operation::result_type>
{
@@ -1068,13 +1076,13 @@ public:
};
template <class __Operation, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
binder2nd<__Operation>
bind2nd(const __Operation& __op, const _Tp& __x)
{return binder2nd<__Operation>(__op, __x);}
template <class _Arg, class _Result>
-class _LIBCPP_TEMPLATE_VIS pointer_to_unary_function
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
: public unary_function<_Arg, _Result>
{
_Result (*__f_)(_Arg);
@@ -1086,13 +1094,13 @@ public:
};
template <class _Arg, class _Result>
-inline _LIBCPP_INLINE_VISIBILITY
+_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);}
template <class _Arg1, class _Arg2, class _Result>
-class _LIBCPP_TEMPLATE_VIS pointer_to_binary_function
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
: public binary_function<_Arg1, _Arg2, _Result>
{
_Result (*__f_)(_Arg1, _Arg2);
@@ -1104,13 +1112,14 @@ public:
};
template <class _Arg1, class _Arg2, class _Result>
-inline _LIBCPP_INLINE_VISIBILITY
+_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);}
template<class _Sp, class _Tp>
-class _LIBCPP_TEMPLATE_VIS mem_fun_t : public unary_function<_Tp*, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
+ : public unary_function<_Tp*, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -1121,7 +1130,8 @@ public:
};
template<class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TEMPLATE_VIS mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
+ : public binary_function<_Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -1132,19 +1142,20 @@ public:
};
template<class _Sp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_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<class _Sp, class _Tp, class _Ap>
-inline _LIBCPP_INLINE_VISIBILITY
+_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 _Sp, class _Tp>
-class _LIBCPP_TEMPLATE_VIS mem_fun_ref_t : public unary_function<_Tp, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
+ : public unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -1155,7 +1166,8 @@ public:
};
template<class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TEMPLATE_VIS mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
+ : public binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -1166,19 +1178,20 @@ public:
};
template<class _Sp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_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<class _Sp, class _Tp, class _Ap>
-inline _LIBCPP_INLINE_VISIBILITY
+_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 _Sp, class _Tp>
-class _LIBCPP_TEMPLATE_VIS const_mem_fun_t : public unary_function<const _Tp*, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
+ : public unary_function<const _Tp*, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -1189,7 +1202,8 @@ public:
};
template <class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TEMPLATE_VIS const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
+ : public binary_function<const _Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
public:
@@ -1200,19 +1214,20 @@ public:
};
template <class _Sp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_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 <class _Sp, class _Tp, class _Ap>
-inline _LIBCPP_INLINE_VISIBILITY
+_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 _Sp, class _Tp>
-class _LIBCPP_TEMPLATE_VIS const_mem_fun_ref_t : public unary_function<_Tp, _Sp>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
+ : public unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -1223,7 +1238,7 @@ public:
};
template <class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TEMPLATE_VIS const_mem_fun1_ref_t
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
: public binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
@@ -1235,13 +1250,13 @@ public:
};
template <class _Sp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_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 <class _Sp, class _Tp, class _Ap>
-inline _LIBCPP_INLINE_VISIBILITY
+_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);}
@@ -1405,7 +1420,7 @@ void __throw_bad_function_call()
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_function_call();
#else
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -1458,6 +1473,81 @@ bool __not_null(function<_Fp> const& __f) { return !!__f; }
namespace __function {
+// __alloc_func holds a functor and an allocator.
+
+template <class _Fp, class _Ap, class _FB> class __alloc_func;
+
+template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
+class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
+{
+ __compressed_pair<_Fp, _Ap> __f_;
+
+ public:
+ typedef _Fp _Target;
+ typedef _Ap _Alloc;
+
+ _LIBCPP_INLINE_VISIBILITY
+ const _Target& __target() const { return __f_.first(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ const _Alloc& __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>(); }
+};
+
+// __base provides an abstract interface for copyable functors.
+
template<class _Fp> class __base;
template<class _Rp, class ..._ArgTypes>
@@ -1479,37 +1569,37 @@ public:
#endif // _LIBCPP_NO_RTTI
};
+// __func implements __base for a given functor type.
+
template<class _FD, class _Alloc, class _FB> class __func;
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
: public __base<_Rp(_ArgTypes...)>
{
- __compressed_pair<_Fp, _Alloc> __f_;
+ __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
public:
_LIBCPP_INLINE_VISIBILITY
explicit __func(_Fp&& __f)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
- _VSTD::forward_as_tuple()) {}
+ : __f_(_VSTD::move(__f)) {}
+
_LIBCPP_INLINE_VISIBILITY
explicit __func(const _Fp& __f, const _Alloc& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
- _VSTD::forward_as_tuple(__a)) {}
+ : __f_(__f, __a) {}
_LIBCPP_INLINE_VISIBILITY
explicit __func(const _Fp& __f, _Alloc&& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
- _VSTD::forward_as_tuple(_VSTD::move(__a))) {}
+ : __f_(__f, _VSTD::move(__a)) {}
_LIBCPP_INLINE_VISIBILITY
explicit __func(_Fp&& __f, _Alloc&& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
- _VSTD::forward_as_tuple(_VSTD::move(__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);
+ 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;
@@ -1522,10 +1612,10 @@ __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_.second());
+ _Ap __a(__f_.__allocator());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
- ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+ ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
return __hold.release();
}
@@ -1533,14 +1623,14 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
{
- ::new (__p) __func(__f_.first(), __f_.second());
+ ::new (__p) __func(__f_.__target(), __f_.__allocator());
}
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
{
- __f_.~__compressed_pair<_Fp, _Alloc>();
+ __f_.destroy();
}
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -1549,8 +1639,8 @@ __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_.second());
- __f_.~__compressed_pair<_Fp, _Alloc>();
+ _Ap __a(__f_.__allocator());
+ __f_.destroy();
__a.deallocate(this, 1);
}
@@ -1558,8 +1648,7 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
_Rp
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
{
- typedef __invoke_void_return_wrapper<_Rp> _Invoker;
- return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
+ return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
#ifndef _LIBCPP_NO_RTTI
@@ -1569,7 +1658,7 @@ const void*
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
{
if (__ti == typeid(_Fp))
- return &__f_.first();
+ return &__f_.__target();
return (const void*)0;
}
@@ -1582,6 +1671,493 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
#endif // _LIBCPP_NO_RTTI
+// __value_func creates a value-type from a __func.
+
+template <class _Fp> class __value_func;
+
+template <class _Rp, class... _ArgTypes> 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_(0) {}
+
+ template <class _Fp, class _Alloc>
+ _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc __a)
+ : __f_(0)
+ {
+ 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();
+ }
+ }
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func(const __value_func& __f)
+ {
+ if (__f.__f_ == 0)
+ __f_ = 0;
+ 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_ == 0)
+ __f_ = 0;
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f_ = __as_base(&__buf_);
+ __f.__f_->__clone(__f_);
+ }
+ else
+ {
+ __f_ = __f.__f_;
+ __f.__f_ = 0;
+ }
+ }
+
+ _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_ == 0)
+ __f_ = 0;
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f_ = __as_base(&__buf_);
+ __f.__f_->__clone(__f_);
+ }
+ else
+ {
+ __f_ = __f.__f_;
+ __f.__f_ = 0;
+ }
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func& operator=(nullptr_t)
+ {
+ __func* __f = __f_;
+ __f_ = 0;
+ if ((void*)__f == &__buf_)
+ __f->destroy();
+ else if (__f)
+ __f->destroy_deallocate();
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ _Rp operator()(_ArgTypes&&... __args) const
+ {
+ if (__f_ == 0)
+ __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<sizeof(__buf_)>::type __tempbuf;
+ __func* __t = __as_base(&__tempbuf);
+ __f_->__clone(__t);
+ __f_->destroy();
+ __f_ = 0;
+ __f.__f_->__clone(__as_base(&__buf_));
+ __f.__f_->destroy();
+ __f.__f_ = 0;
+ __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
+ _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != 0; }
+
+#ifndef _LIBCPP_NO_RTTI
+ _LIBCPP_INLINE_VISIBILITY
+ const std::type_info& target_type() const _NOEXCEPT
+ {
+ if (__f_ == 0)
+ return typeid(void);
+ return __f_->target_type();
+ }
+
+ template <typename _Tp>
+ _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
+ {
+ if (__f_ == 0)
+ return 0;
+ 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 <typename _Fun>
+struct __use_small_storage
+ : public _VSTD::integral_constant<
+ bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
+ _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
+ _VSTD::is_trivially_copy_constructible<_Fun>::value &&
+ _VSTD::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 <typename _Fun>
+ _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 <typename _Fun> static void* __large_clone(const void* __s)
+ {
+ const _Fun* __f = static_cast<const _Fun*>(__s);
+ return __f->__clone();
+ }
+
+ template <typename _Fun> static void __large_destroy(void* __s)
+ {
+ typedef allocator_traits<typename _Fun::_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
+ _FunAlloc;
+ _Fun* __f = static_cast<_Fun*>(__s);
+ _FunAlloc __a(__f->__allocator());
+ __f->destroy();
+ __a.deallocate(__f, 1);
+ }
+
+ template <typename _Fun>
+ _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 <typename _Fun>
+ _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 <typename _Tp>
+using __fast_forward =
+ typename _VSTD::conditional<_VSTD::is_scalar<_Tp>::value, _Tp, _Tp&&>::type;
+
+// __policy_invoker calls an instance of __alloc_func held in __policy_storage.
+
+template <class _Fp> struct __policy_invoker;
+
+template <class _Rp, class... _ArgTypes>
+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 <typename _Fun>
+ _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 <typename _Fun>
+ 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 _Fp> class __policy_func;
+
+template <class _Rp, class... _ArgTypes> 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 <class _Fp, class _Alloc>
+ _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();
+ }
+ }
+ }
+
+ _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 <typename _Tp>
+ _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<const _Tp*>(__buf_.__large);
+ else
+ return reinterpret_cast<const _Tp*>(&__buf_.__small);
+ }
+#endif // _LIBCPP_NO_RTTI
+};
+
} // __function
template<class _Rp, class ..._ArgTypes>
@@ -1589,13 +2165,13 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
: public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
{
- typedef __function::__base<_Rp(_ArgTypes...)> __base;
- typename aligned_storage<3*sizeof(void*)>::type __buf_;
- __base* __f_;
+#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
+ typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
+#else
+ typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
+#endif
- _LIBCPP_NO_CFI static __base *__as_base(void *p) {
- return reinterpret_cast<__base*>(p);
- }
+ __func __f_;
template <class _Fp, bool = __lazy_and<
integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
@@ -1622,9 +2198,9 @@ public:
// construct/copy/destroy:
_LIBCPP_INLINE_VISIBILITY
- function() _NOEXCEPT : __f_(0) {}
+ function() _NOEXCEPT { }
_LIBCPP_INLINE_VISIBILITY
- function(nullptr_t) _NOEXCEPT : __f_(0) {}
+ function(nullptr_t) _NOEXCEPT {}
function(const function&);
function(function&&) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<_Fp>>
@@ -1633,10 +2209,10 @@ public:
#if _LIBCPP_STD_VER <= 14
template<class _Alloc>
_LIBCPP_INLINE_VISIBILITY
- function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {}
+ function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
template<class _Alloc>
_LIBCPP_INLINE_VISIBILITY
- function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {}
+ function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
template<class _Alloc>
function(allocator_arg_t, const _Alloc&, const function&);
template<class _Alloc>
@@ -1665,7 +2241,9 @@ public:
// function capacity:
_LIBCPP_INLINE_VISIBILITY
- _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;}
+ _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
+ return static_cast<bool>(__f_);
+ }
// deleted overloads close possible hole in the type system
template<class _R2, class... _ArgTypes2>
@@ -1685,125 +2263,38 @@ public:
};
template<class _Rp, class ..._ArgTypes>
-function<_Rp(_ArgTypes...)>::function(const function& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- __f_ = __f.__f_->__clone();
-}
+function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
#if _LIBCPP_STD_VER <= 14
template<class _Rp, class ..._ArgTypes>
template <class _Alloc>
function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
- const function& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- __f_ = __f.__f_->__clone();
-}
+ const function& __f) : __f_(__f.__f_) {}
#endif
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
-}
+ : __f_(_VSTD::move(__f.__f_)) {}
#if _LIBCPP_STD_VER <= 14
template<class _Rp, class ..._ArgTypes>
template <class _Alloc>
function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
- function&& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
-}
+ function&& __f)
+ : __f_(_VSTD::move(__f.__f_)) {}
#endif
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
template <class _Fp, class>
function<_Rp(_ArgTypes...)>::function(_Fp __f)
- : __f_(0)
-{
- if (__function::__not_null(__f))
- {
- typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;
- if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)
- {
- __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__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(_VSTD::move(__f), allocator<_Fp>(__a));
- __f_ = __hold.release();
- }
- }
-}
+ : __f_(_VSTD::move(__f), allocator<_Fp>()) {}
#if _LIBCPP_STD_VER <= 14
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
template <class _Fp, class _Alloc, class>
-function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f)
- : __f_(0)
-{
- typedef allocator_traits<_Alloc> __alloc_traits;
- if (__function::__not_null(__f))
- {
- typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
- typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
- _Ap __a(__a0);
- if (sizeof(_FF) <= sizeof(__buf_) &&
- is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
- {
- __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a));
- }
- else
- {
- typedef __allocator_destructor<_Ap> _Dp;
- unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
- ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a));
- __f_ = __hold.release();
- }
- }
-}
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
+ _Fp __f)
+ : __f_(_VSTD::move(__f), __a) {}
#endif
template<class _Rp, class ..._ArgTypes>
@@ -1818,19 +2309,7 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
{
- *this = nullptr;
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
+ __f_ = std::move(__f.__f_);
return *this;
}
@@ -1838,12 +2317,7 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
{
- __base* __t = __f_;
- __f_ = 0;
- if ((void *)__t == &__buf_)
- __t->destroy();
- else if (__t)
- __t->destroy_deallocate();
+ __f_ = nullptr;
return *this;
}
@@ -1857,60 +2331,20 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
}
template<class _Rp, class ..._ArgTypes>
-function<_Rp(_ArgTypes...)>::~function()
-{
- if ((void *)__f_ == &__buf_)
- __f_->destroy();
- else if (__f_)
- __f_->destroy_deallocate();
-}
+function<_Rp(_ArgTypes...)>::~function() {}
template<class _Rp, class ..._ArgTypes>
void
function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
{
- if (_VSTD::addressof(__f) == this)
- return;
- if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_)
- {
- typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
- __base* __t = __as_base(&__tempbuf);
- __f_->__clone(__t);
- __f_->destroy();
- __f_ = 0;
- __f.__f_->__clone(__as_base(&__buf_));
- __f.__f_->destroy();
- __f.__f_ = 0;
- __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_);
+ __f_.swap(__f.__f_);
}
template<class _Rp, class ..._ArgTypes>
_Rp
function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
{
- if (__f_ == 0)
- __throw_bad_function_call();
- return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
+ return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
#ifndef _LIBCPP_NO_RTTI
@@ -1919,9 +2353,7 @@ template<class _Rp, class ..._ArgTypes>
const std::type_info&
function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
{
- if (__f_ == 0)
- return typeid(void);
- return __f_->target_type();
+ return __f_.target_type();
}
template<class _Rp, class ..._ArgTypes>
@@ -1929,9 +2361,7 @@ template <typename _Tp>
_Tp*
function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
{
- if (__f_ == 0)
- return nullptr;
- return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+ return (_Tp*)(__f_.template target<_Tp>());
}
template<class _Rp, class ..._ArgTypes>
@@ -1939,9 +2369,7 @@ template <typename _Tp>
const _Tp*
function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
{
- if (__f_ == 0)
- return nullptr;
- return (const _Tp*)__f_->target(typeid(_Tp));
+ return __f_.template target<_Tp>();
}
#endif // _LIBCPP_NO_RTTI
@@ -2105,53 +2533,53 @@ __mu(_Ti& __ti, _Uj&)
template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
class _TupleUj>
-struct ____mu_return;
+struct __mu_return_impl;
template <bool _Invokable, class _Ti, class ..._Uj>
-struct ____mu_return_invokable // false
+struct __mu_return_invokable // false
{
typedef __nat type;
};
template <class _Ti, class ..._Uj>
-struct ____mu_return_invokable<true, _Ti, _Uj...>
+struct __mu_return_invokable<true, _Ti, _Uj...>
{
typedef typename __invoke_of<_Ti&, _Uj...>::type type;
};
template <class _Ti, class ..._Uj>
-struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >
- : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
+struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
+ : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
{
};
template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, false, true, _TupleUj>
+struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
{
typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
_TupleUj>::type&& type;
};
template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, true, false, false, _TupleUj>
+struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
{
typedef typename _Ti::type& type;
};
template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, false, false, _TupleUj>
+struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
{
typedef _Ti& type;
};
template <class _Ti, class _TupleUj>
struct __mu_return
- : public ____mu_return<_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>
+ : 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>
{
};
@@ -2340,8 +2768,6 @@ bind(_Fp&& __f, _BoundArgs&&... __bound_args)
#if _LIBCPP_STD_VER > 14
-#define __cpp_lib_invoke 201411
-
template <class _Fn, class ..._Args>
result_of_t<_Fn&&(_Args&&...)>
invoke(_Fn&& __f, _Args&&... __args)
@@ -2497,7 +2923,7 @@ template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
class _LIBCPP_TYPE_VIS default_searcher {
public:
_LIBCPP_INLINE_VISIBILITY
- default_searcher(_ForwardIterator __f, _ForwardIterator __l,
+ default_searcher(_ForwardIterator __f, _ForwardIterator __l,
_BinaryPredicate __p = _BinaryPredicate())
: __first_(__f), __last_(__l), __pred_(__p) {}
@@ -2519,6 +2945,26 @@ private:
#endif // _LIBCPP_STD_VER > 14
+#if _LIBCPP_STD_VER > 17
+template <class _Tp>
+using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
+
+template <class _Tp>
+using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
+#endif // > C++17
+
+template <class _Container, class _Predicate>
+inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred)
+{
+ for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;)
+ {
+ if (__pred(*__iter))
+ __iter = __c.erase(__iter);
+ else
+ ++__iter;
+ }
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_FUNCTIONAL
diff --git a/include/future b/include/future
index 0f6d42678ef5..b3ffc7e35177 100644
--- a/include/future
+++ b/include/future
@@ -556,13 +556,14 @@ public:
{return (__state_ & __constructed) || (__exception_ != nullptr);}
_LIBCPP_INLINE_VISIBILITY
- void __set_future_attached()
- {
+ void __attach_future() {
lock_guard<mutex> __lk(__mut_);
+ bool __has_future_attached = (__state_ & __future_attached) != 0;
+ if (__has_future_attached)
+ __throw_future_error(future_errc::future_already_retrieved);
+ this->__add_shared();
__state_ |= __future_attached;
}
- _LIBCPP_INLINE_VISIBILITY
- bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
_LIBCPP_INLINE_VISIBILITY
void __set_deferred() {__state_ |= deferred;}
@@ -1154,10 +1155,7 @@ template <class _Rp>
future<_Rp>::future(__assoc_state<_Rp>* __state)
: __state_(__state)
{
- if (__state_->__has_future_attached())
- __throw_future_error(future_errc::future_already_retrieved);
- __state_->__add_shared();
- __state_->__set_future_attached();
+ __state_->__attach_future();
}
struct __release_shared_count
@@ -1257,10 +1255,7 @@ template <class _Rp>
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
: __state_(__state)
{
- if (__state_->__has_future_attached())
- __throw_future_error(future_errc::future_already_retrieved);
- __state_->__add_shared();
- __state_->__set_future_attached();
+ __state_->__attach_future();
}
template <class _Rp>
diff --git a/include/iomanip b/include/iomanip
index a6bee736f45b..36c11167a44e 100644
--- a/include/iomanip
+++ b/include/iomanip
@@ -46,6 +46,7 @@ template <class charT, class traits, class Allocator>
#include <__config>
#include <__string>
#include <istream>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
diff --git a/include/iosfwd b/include/iosfwd
index d4384859e418..31f1902e5f59 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -18,6 +18,12 @@ namespace std
{
template<class charT> struct char_traits;
+template<> struct char_traits<char>;
+template<> struct char_traits<char8_t>; // C++20
+template<> struct char_traits<char16_t>;
+template<> struct char_traits<char32_t>;
+template<> struct char_traits<wchar_t>;
+
template<class T> class allocator;
class ios_base;
@@ -98,6 +104,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS ios_base;
template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits;
+template<> struct char_traits<char>;
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+template<> struct char_traits<char8_t>;
+#endif
+template<> struct char_traits<char16_t>;
+template<> struct char_traits<char32_t>;
+template<> struct char_traits<wchar_t>;
+
template<class _Tp> class _LIBCPP_TEMPLATE_VIS allocator;
template <class _CharT, class _Traits = char_traits<_CharT> >
@@ -175,6 +189,9 @@ typedef basic_fstream<wchar_t> wfstream;
template <class _State> class _LIBCPP_TEMPLATE_VIS fpos;
typedef fpos<mbstate_t> streampos;
typedef fpos<mbstate_t> wstreampos;
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+typedef fpos<mbstate_t> u8streampos;
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef fpos<mbstate_t> u16streampos;
typedef fpos<mbstate_t> u32streampos;
diff --git a/include/istream b/include/istream
index 71c162b0d41a..30ee4f4b8710 100644
--- a/include/istream
+++ b/include/istream
@@ -160,6 +160,7 @@ template <class charT, class traits, class T>
*/
#include <__config>
+#include <version>
#include <ostream>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -186,7 +187,7 @@ public:
typedef typename traits_type::off_type off_type;
// 27.7.1.1.1 Constructor/destructor:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0)
{ this->init(__sb); }
virtual ~basic_istream();
@@ -200,7 +201,7 @@ protected:
basic_istream& operator=(basic_istream&& __rhs);
#endif
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_istream& __rhs) {
_VSTD::swap(__gc_, __rhs.__gc_);
basic_ios<char_type, traits_type>::swap(__rhs);
@@ -216,16 +217,16 @@ public:
class _LIBCPP_TEMPLATE_VIS sentry;
// 27.7.1.2 Formatted input:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&))
{ return __pf(*this); }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(basic_ios<char_type, traits_type>&
(*__pf)(basic_ios<char_type, traits_type>&))
{ __pf(*this); return *this; }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(ios_base& (*__pf)(ios_base&))
{ __pf(*this); return *this; }
@@ -249,7 +250,7 @@ public:
streamsize gcount() const {return __gc_;}
int_type get();
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(char_type& __c) {
int_type __ch = get();
if (__ch != traits_type::eof())
@@ -257,19 +258,19 @@ public:
return *this;
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(char_type* __s, streamsize __n)
{ return get(__s, __n, this->widen('\n')); }
basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(basic_streambuf<char_type, traits_type>& __sb)
{ return get(__sb, this->widen('\n')); }
basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& getline(char_type* __s, streamsize __n)
{ return getline(__s, __n, this->widen('\n')); }
@@ -517,8 +518,9 @@ basic_istream<_CharT, _Traits>::operator>>(int& __n)
}
template<class _CharT, class _Traits>
+_LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
-operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
+__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -527,13 +529,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
if (__sen)
{
- streamsize __n = __is.width();
- if (__n <= 0)
- __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
- streamsize __c = 0;
+ auto __s = __p;
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
ios_base::iostate __err = ios_base::goodbit;
- while (__c < __n-1)
+ while (__s != __p + (__n-1))
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
if (_Traits::eq_int_type(__i, _Traits::eof()))
@@ -545,12 +544,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
if (__ct.is(__ct.space, __ch))
break;
*__s++ = __ch;
- ++__c;
__is.rdbuf()->sbumpc();
}
*__s = _CharT();
__is.width(0);
- if (__c == 0)
+ if (__s == __p)
__err |= ios_base::failbit;
__is.setstate(__err);
}
@@ -564,6 +562,48 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
return __is;
}
+#if _LIBCPP_STD_VER > 17
+
+template<class _CharT, class _Traits, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np])
+{
+ auto __n = _Np;
+ if (__is.width() > 0)
+ __n = _VSTD::min(size_t(__is.width()), _Np);
+ return _VSTD::__input_c_string(__is, __buf, __n);
+}
+
+template<class _Traits, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, unsigned char (&__buf)[_Np])
+{
+ return __is >> (char(&)[_Np])__buf;
+}
+
+template<class _Traits, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, signed char (&__buf)[_Np])
+{
+ return __is >> (char(&)[_Np])__buf;
+}
+
+#else
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
+{
+ streamsize __n = __is.width();
+ if (__n <= 0)
+ __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
+ return _VSTD::__input_c_string(__is, __s, size_t(__n));
+}
+
template<class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<char, _Traits>&
@@ -580,6 +620,8 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
return __is >> (char*)__s;
}
+#endif // _LIBCPP_STD_VER > 17
+
template<class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
@@ -1238,7 +1280,7 @@ public:
typedef typename traits_type::off_type off_type;
// constructor/destructor
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
: basic_istream<_CharT, _Traits>(__sb)
{}
@@ -1253,7 +1295,7 @@ protected:
inline _LIBCPP_INLINE_VISIBILITY
basic_iostream& operator=(basic_iostream&& __rhs);
#endif
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_iostream& __rhs)
{ basic_istream<char_type, traits_type>::swap(__rhs); }
public:
@@ -1463,7 +1505,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
return __is;
}
-#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
+#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>)
diff --git a/include/iterator b/include/iterator
index 9415e0b83967..bda177e11e6c 100644
--- a/include/iterator
+++ b/include/iterator
@@ -418,6 +418,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <type_traits>
#include <cstddef>
#include <initializer_list>
+#include <version>
#ifdef __APPLE__
#include <Availability.h>
#endif
@@ -437,6 +438,23 @@ struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator
struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
template <class _Tp>
+struct __has_iterator_typedefs
+{
+private:
+ struct __two {char __lx; char __lxx;};
+ template <class _Up> static __two __test(...);
+ template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0,
+ typename std::__void_t<typename _Up::difference_type>::type* = 0,
+ typename std::__void_t<typename _Up::value_type>::type* = 0,
+ typename std::__void_t<typename _Up::reference>::type* = 0,
+ typename std::__void_t<typename _Up::pointer>::type* = 0
+ );
+public:
+ static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
+};
+
+
+template <class _Tp>
struct __has_iterator_category
{
private:
@@ -478,7 +496,7 @@ struct __iterator_traits<_Iter, true>
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits
- : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
+ : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {};
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
diff --git a/include/limits b/include/limits
index f530507f7246..5ea9a9e6fdfa 100644
--- a/include/limits
+++ b/include/limits
@@ -82,6 +82,7 @@ template<> class numeric_limits<cv char>;
template<> class numeric_limits<cv signed char>;
template<> class numeric_limits<cv unsigned char>;
template<> class numeric_limits<cv wchar_t>;
+template<> class numeric_limits<cv char8_t>; // C++20
template<> class numeric_limits<cv char16_t>;
template<> class numeric_limits<cv char32_t>;
@@ -118,6 +119,7 @@ template<> class numeric_limits<cv long double>;
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
+#include <version>
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/include/list b/include/list
index d2e78cd66afb..c69e31d93a44 100644
--- a/include/list
+++ b/include/list
@@ -169,6 +169,11 @@ template <class T, class Alloc>
void swap(list<T,Alloc>& x, list<T,Alloc>& y)
noexcept(noexcept(x.swap(y)));
+template <class T, class Allocator, class U>
+ void erase(list<T, Allocator>& c, const U& value); // C++20
+template <class T, class Allocator, class Predicate>
+ void erase_if(list<T, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -181,6 +186,7 @@ template <class T, class Alloc>
#include <iterator>
#include <algorithm>
#include <type_traits>
+#include <version>
#include <__debug>
@@ -1169,7 +1175,7 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
base::__end_.__next_ = __f;
}
-// Link in nodes [__f, __l] at the front of the list
+// Link in nodes [__f, __l] at the back of the list
template <class _Tp, class _Alloc>
inline
void
@@ -2208,7 +2214,7 @@ template <class _Comp>
void
list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
{
- if (this != &__c)
+ if (this != _VSTD::addressof(__c))
{
iterator __f1 = begin();
iterator __e1 = end();
@@ -2449,6 +2455,18 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred)
+{ __c.remove_if(__pred); }
+
+template <class _Tp, class _Allocator, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase(list<_Tp, _Allocator>& __c, const _Up& __v)
+{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
+#endif
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/include/locale b/include/locale
index e240799f3831..2043892fa2dc 100644
--- a/include/locale
+++ b/include/locale
@@ -187,6 +187,7 @@ template <class charT> class messages_byname;
#include <streambuf>
#include <iterator>
#include <limits>
+#include <version>
#ifndef __APPLE__
#include <cstdarg>
#endif
@@ -727,7 +728,7 @@ locale::id
num_get<_CharT, _InputIterator>::id;
template <class _Tp>
-_Tp
+_LIBCPP_HIDDEN _Tp
__num_get_signed_integral(const char* __a, const char* __a_end,
ios_base::iostate& __err, int __base)
{
@@ -762,7 +763,7 @@ __num_get_signed_integral(const char* __a, const char* __a_end,
}
template <class _Tp>
-_Tp
+_LIBCPP_HIDDEN _Tp
__num_get_unsigned_integral(const char* __a, const char* __a_end,
ios_base::iostate& __err, int __base)
{
@@ -2408,6 +2409,23 @@ private:
string_type __analyze(char __fmt, const ctype<_CharT>&);
};
+#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
+template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
+template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
+extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
+extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
+/**/
+
+_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
+_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
+#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
+
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class _LIBCPP_TEMPLATE_VIS time_get_byname
: public time_get<_CharT, _InputIterator>,
@@ -3550,6 +3568,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
__cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
return __cat;
#else // !_LIBCPP_HAS_CATOPEN
+ _LIBCPP_UNUSED_VAR(__nm);
return -1;
#endif // _LIBCPP_HAS_CATOPEN
}
@@ -3573,6 +3592,9 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
__n, __n + strlen(__n));
return __w;
#else // !_LIBCPP_HAS_CATOPEN
+ _LIBCPP_UNUSED_VAR(__c);
+ _LIBCPP_UNUSED_VAR(__set);
+ _LIBCPP_UNUSED_VAR(__msgid);
return __dflt;
#endif // _LIBCPP_HAS_CATOPEN
}
@@ -3586,6 +3608,8 @@ messages<_CharT>::do_close(catalog __c) const
__c <<= 1;
nl_catd __cat = (nl_catd)__c;
catclose(__cat);
+#else // !_LIBCPP_HAS_CATOPEN
+ _LIBCPP_UNUSED_VAR(__c);
#endif // _LIBCPP_HAS_CATOPEN
}
diff --git a/include/map b/include/map
index 559ec484aca0..616bb46cfccd 100644
--- a/include/map
+++ b/include/map
@@ -167,6 +167,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class C2>
+ void merge(map<Key, T, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(map<Key, T, C2, Allocator>&& source); // C++17
+ template<class C2>
+ void merge(multimap<Key, T, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
+
void swap(map& m)
noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
is_nothrow_swappable<key_compare>::value); // C++17
@@ -245,6 +254,10 @@ void
swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class Key, class T, class Compare, class Allocator, class Predicate>
+ void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
+
+
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T>>>
class multimap
@@ -368,6 +381,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class C2>
+ void merge(multimap<Key, T, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
+ template<class C2>
+ void merge(map<Key, T, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(map<Key, T, C2, Allocator>&& source); // C++17
+
void swap(multimap& m)
noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
is_nothrow_swappable<key_compare>::value); // C++17
@@ -447,6 +469,9 @@ swap(multimap<Key, T, Compare, Allocator>& x,
multimap<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class Key, class T, class Compare, class Allocator, class Predicate>
+ void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -460,6 +485,7 @@ swap(multimap<Key, T, Compare, Allocator>& x,
#include <functional>
#include <initializer_list>
#include <type_traits>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -467,7 +493,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Key, class _CP, class _Compare, bool _IsSmall>
+template <class _Key, class _CP, class _Compare,
+ bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
class __map_value_compare
: private _Compare
{
@@ -881,6 +908,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
+ static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@@ -925,6 +953,11 @@ public:
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
+ template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS map;
+ template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS multimap;
+
_LIBCPP_INLINE_VISIBILITY
map()
_NOEXCEPT_(
@@ -1299,6 +1332,38 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -1556,6 +1621,14 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
+
template <class _Key, class _Tp, class _Compare = less<_Key>,
class _Allocator = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_TEMPLATE_VIS multimap
@@ -1570,6 +1643,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
+ static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@@ -1614,6 +1688,11 @@ public:
typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
#endif
+ template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS map;
+ template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS multimap;
+
_LIBCPP_INLINE_VISIBILITY
multimap()
_NOEXCEPT_(
@@ -1881,10 +1960,42 @@ public:
return __tree_.template __node_handle_extract<node_type>(
__it.__i_);
}
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
- void clear() {__tree_.clear();}
+ void clear() _NOEXCEPT {__tree_.clear();}
_LIBCPP_INLINE_VISIBILITY
void swap(multimap& __m)
@@ -2055,6 +2166,13 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_MAP
diff --git a/include/memory b/include/memory
index a4bf89b495ad..ce2c35766233 100644
--- a/include/memory
+++ b/include/memory
@@ -43,7 +43,7 @@ struct pointer_traits<T*>
template <class U> using rebind = U*;
- static pointer pointer_to(<details>) noexcept;
+ static pointer pointer_to(<details>) noexcept; // constexpr in C++20
};
template <class T> constexpr T* to_address(T* p) noexcept; // C++20
@@ -212,10 +212,10 @@ template <class ForwardIterator>
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
-template <class Y> struct auto_ptr_ref {}; // removed in C++17
+template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17
template<class X>
-class auto_ptr // removed in C++17
+class auto_ptr // deprecated in C++11, removed in C++17
{
public:
typedef X element_type;
@@ -667,6 +667,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -983,7 +984,7 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
private:
struct __nat {};
public:
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
static pointer pointer_to(typename conditional<is_void<element_type>::value,
__nat, element_type>::type& __r) _NOEXCEPT
{return _VSTD::addressof(__r);}
@@ -1459,29 +1460,21 @@ struct __has_select_on_container_copy_construction
#else // _LIBCPP_CXX03_LANG
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class ..._Args>
-struct __has_construct
- : false_type
-{
-};
-
-#else // _LIBCPP_HAS_NO_VARIADICS
+template <class _Alloc, class _Pointer, class _Tp, class = void>
+struct __has_construct : std::false_type {};
-template <class _Alloc, class _Pointer, class _Args>
-struct __has_construct
- : false_type
-{
-};
+template <class _Alloc, class _Pointer, class _Tp>
+struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
+ decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
+>::type> : std::true_type {};
-#endif // _LIBCPP_HAS_NO_VARIADICS
+template <class _Alloc, class _Pointer, class = void>
+struct __has_destroy : false_type {};
template <class _Alloc, class _Pointer>
-struct __has_destroy
- : false_type
-{
-};
+struct __has_destroy<_Alloc, _Pointer, typename __void_t<
+ decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
+>::type> : std::true_type {};
template <class _Alloc>
struct __has_max_size
@@ -1509,6 +1502,12 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true>
typedef typename _Alloc::difference_type type;
};
+template <class _Tp>
+struct __is_default_allocator : false_type {};
+
+template <class _Tp>
+struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {};
+
template <class _Alloc>
struct _LIBCPP_TEMPLATE_VIS allocator_traits
{
@@ -1570,9 +1569,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
- static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
+ static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
{
- ::new ((void*)__p) _Tp(__a0);
+ __construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
+ __a, __p, __a0);
}
template <class _Tp, class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
@@ -1612,7 +1612,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
void
__construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
{
- for (; __begin1 != __end1; ++__begin1, ++__begin2)
+ for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));
}
@@ -1621,7 +1621,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static
typename enable_if
<
- (is_same<allocator_type, allocator<_Tp> >::value
+ (__is_default_allocator<allocator_type>::value
|| !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
@@ -1646,23 +1646,25 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
}
- template <class _Tp>
+ template <class _SourceTp, class _DestTp,
+ class _RawSourceTp = typename remove_const<_SourceTp>::type,
+ class _RawDestTp = typename remove_const<_DestTp>::type>
_LIBCPP_INLINE_VISIBILITY
static
typename enable_if
<
- (is_same<allocator_type, allocator<_Tp> >::value
- || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
- is_trivially_move_constructible<_Tp>::value,
+ is_trivially_move_constructible<_DestTp>::value &&
+ is_same<_RawSourceTp, _RawDestTp>::value &&
+ (__is_default_allocator<allocator_type>::value ||
+ !__has_construct<allocator_type, _DestTp*, _SourceTp&>::value),
void
>::type
- __construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
+ __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2)
{
- typedef typename remove_const<_Tp>::type _Vp;
ptrdiff_t _Np = __end1 - __begin1;
if (_Np > 0)
{
- _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp));
+ _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp));
__begin2 += _Np;
}
}
@@ -1685,7 +1687,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static
typename enable_if
<
- (is_same<allocator_type, allocator<_Tp> >::value
+ (__is_default_allocator<allocator_type>::value
|| !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
@@ -1720,6 +1722,19 @@ private:
{
::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
}
+#else // _LIBCPP_HAS_NO_VARIADICS
+ template <class _Tp, class _A0>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __construct(true_type, allocator_type& __a, _Tp* __p,
+ const _A0& __a0)
+ {__a.construct(__p, __a0);}
+ template <class _Tp, class _A0>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __construct(false_type, allocator_type&, _Tp* __p,
+ const _A0& __a0)
+ {
+ ::new ((void*)__p) _Tp(__a0);
+ }
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
@@ -1782,7 +1797,7 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator() _NOEXCEPT {}
- template <class _Up>
+ template <class _Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
@@ -1790,16 +1805,16 @@ public:
{return _VSTD::addressof(__x);}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
{return _VSTD::addressof(__x);}
- _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
{
if (__n > max_size())
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
- _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));}
+ _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
+ {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1887,7 +1902,7 @@ public:
allocator() _NOEXCEPT {}
template <class _Up>
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
@@ -1897,10 +1912,10 @@ public:
if (__n > max_size())
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
- _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __alignof(_Tp));}
+ _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
+ {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1989,10 +2004,10 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
- {::new(&*__x_) _Tp(__element); return *this;}
+ {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
#if _LIBCPP_STD_VER >= 14
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
- {::new(&*__x_) _Tp(_VSTD::move(__element)); return *this;}
+ {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
#endif
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int)
@@ -2003,7 +2018,7 @@ public:
};
template <class _Tp>
-_LIBCPP_NO_CFI
+_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
{
@@ -2016,7 +2031,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
while (__n > 0)
{
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
- if (__is_overaligned_for_new(__alignof(_Tp)))
+ if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
std::align_val_t __al =
std::align_val_t(std::alignment_of<_Tp>::value);
@@ -2027,7 +2042,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
__n * sizeof(_Tp), nothrow));
}
#else
- if (__is_overaligned_for_new(__alignof(_Tp)))
+ if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
// Since aligned operator new is unavailable, return an empty
// buffer rather than one with invalid alignment.
@@ -2051,18 +2066,18 @@ template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
void return_temporary_buffer(_Tp* __p) _NOEXCEPT
{
- _VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));
+ _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
template <class _Tp>
-struct auto_ptr_ref
+struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
{
_Tp* __ptr_;
};
template<class _Tp>
-class _LIBCPP_TEMPLATE_VIS auto_ptr
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
{
private:
_Tp* __ptr_;
@@ -2106,7 +2121,7 @@ public:
};
template <>
-class _LIBCPP_TEMPLATE_VIS auto_ptr<void>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
{
public:
typedef void element_type;
@@ -2130,7 +2145,9 @@ struct __compressed_pair_elem {
_LIBCPP_INLINE_VISIBILITY
constexpr explicit
__compressed_pair_elem(_Up&& __u)
- : __value_(_VSTD::forward<_Up>(__u)){};
+ : __value_(_VSTD::forward<_Up>(__u))
+ {
+ }
template <class... _Args, size_t... _Indexes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -2167,7 +2184,8 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
_LIBCPP_INLINE_VISIBILITY
constexpr explicit
__compressed_pair_elem(_Up&& __u)
- : __value_type(_VSTD::forward<_Up>(__u)){};
+ : __value_type(_VSTD::forward<_Up>(__u))
+ {}
template <class... _Args, size_t... _Indexes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -3682,7 +3700,7 @@ private:
virtual void __on_zero_shared_weak() _NOEXCEPT;
public:
_LIBCPP_INLINE_VISIBILITY
- _Tp* get() _NOEXCEPT {return &__data_.second();}
+ _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());}
};
template <class _Tp, class _Alloc>
@@ -5624,15 +5642,18 @@ template <class _Tp, class _Alloc>
struct __temp_value {
typedef allocator_traits<_Alloc> _Traits;
- typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v;
+ typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
_Alloc &__a;
_Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
_Tp & get() { return *__addr(); }
template<class... _Args>
- __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc)
- { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); }
+ _LIBCPP_NO_CFI
+ __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
+ _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
+ _VSTD::forward<_Args>(__args)...);
+ }
~__temp_value() { _Traits::destroy(__a, __addr()); }
};
diff --git a/include/module.modulemap b/include/module.modulemap
index 089505586fb3..6d88f52113cb 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -228,6 +228,10 @@ module std [system] {
header "atomic"
export *
}
+ module bit {
+ header "bit"
+ export *
+ }
module bitset {
header "bitset"
export string
@@ -520,10 +524,6 @@ module std [system] {
header "experimental/deque"
export *
}
- module dynarray {
- header "experimental/dynarray"
- export *
- }
module filesystem {
header "experimental/filesystem"
export *
diff --git a/include/mutex b/include/mutex
index 52e39b0fb1f8..6d2de2b460e2 100644
--- a/include/mutex
+++ b/include/mutex
@@ -194,6 +194,7 @@ template<class Callable, class ...Args>
#ifndef _LIBCPP_CXX03_LANG
#include <tuple>
#endif
+#include <version>
#include <__threading_support>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -488,7 +489,7 @@ public:
};
template <class _Mutex>
-class _LIBCPP_TEMPLATE_VIS scoped_lock<_Mutex> {
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
public:
typedef _Mutex mutex_type;
private:
diff --git a/include/new b/include/new
index e70b9c621570..24ffcad5a6bc 100644
--- a/include/new
+++ b/include/new
@@ -27,12 +27,6 @@ public:
virtual const char* what() const noexcept;
};
-class bad_array_length : public bad_alloc // FIXME: Not part of C++
-{
-public:
- bad_array_length() noexcept;
-};
-
class bad_array_new_length : public bad_alloc // C++14
{
public:
@@ -91,6 +85,7 @@ void operator delete[](void* ptr, void*) noexcept;
#include <exception>
#include <type_traits>
#include <cstddef>
+#include <version>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif
@@ -103,23 +98,23 @@ void operator delete[](void* ptr, void*) noexcept;
#pragma GCC system_header
#endif
-#if !(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER >= 14 || \
- (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
-# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L
+#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION
#endif
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
- (!(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER > 14 || \
- (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)))
-# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \
+ defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
+# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
#endif
+#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
+ defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
+# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#endif
#if !__has_builtin(__builtin_operator_new) || \
- __has_builtin(__builtin_operator_new) < 201802L || \
- defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
- !defined(__cpp_aligned_new) || __cpp_aligned_new < 201606
-#define _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
+ __has_builtin(__builtin_operator_new) < 201802L
+#define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
#endif
namespace std // purposefully not using versioning namespace
@@ -155,29 +150,14 @@ _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
-#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
-
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
- bad_array_length : public bad_alloc {
-public:
- bad_array_length() _NOEXCEPT;
- virtual ~bad_array_length() _NOEXCEPT;
- virtual const char* what() const _NOEXCEPT;
-};
-
-#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
-
-#endif // defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
-
-#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
+#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
+ !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME)
#ifndef _LIBCPP_CXX03_LANG
enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
#else
enum align_val_t { __zero = 0, __max = (size_t)-1 };
#endif
#endif
-#endif
} // std
@@ -187,13 +167,13 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
#define _THROW_BAD_ALLOC
#endif
-#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
+#if !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME)
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
-#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
#endif
@@ -201,16 +181,16 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
-#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
#endif
-#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
-#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
@@ -218,7 +198,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
-#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
#endif
@@ -228,7 +208,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator ne
inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {}
inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {}
-#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME
+#endif // !_LIBCPP_DEFER_NEW_TO_VCRUNTIME
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -244,7 +224,7 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
-# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
+# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
return ::operator new(__size, __align_val);
# else
return __builtin_operator_new(__size, __align_val);
@@ -260,43 +240,98 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _
#endif
}
-inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __align) {
-#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
- if (__is_overaligned_for_new(__align)) {
- const align_val_t __align_val = static_cast<align_val_t>(__align);
-# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
- return ::operator delete(__ptr, __align_val);
-# else
- return __builtin_operator_delete(__ptr, __align_val);
-# endif
+struct _DeallocateCaller {
+ static inline _LIBCPP_INLINE_VISIBILITY
+ void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) {
+#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+ ((void)__align);
+ return __do_deallocate_handle_size(__ptr, __size);
+#else
+ if (__is_overaligned_for_new(__align)) {
+ const align_val_t __align_val = static_cast<align_val_t>(__align);
+ return __do_deallocate_handle_size(__ptr, __size, __align_val);
+ } else {
+ return __do_deallocate_handle_size(__ptr, __size);
+ }
+#endif
+ }
+
+ static inline _LIBCPP_INLINE_VISIBILITY
+ void __do_deallocate_handle_align(void *__ptr, size_t __align) {
+#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+ ((void)__align);
+ return __do_call(__ptr);
+#else
+ if (__is_overaligned_for_new(__align)) {
+ const align_val_t __align_val = static_cast<align_val_t>(__align);
+ return __do_call(__ptr, __align_val);
+ } else {
+ return __do_call(__ptr);
+ }
+#endif
}
+
+ private:
+ static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) {
+#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+ ((void)__size);
+ return __do_call(__ptr);
#else
- ((void)__align);
+ return __do_call(__ptr, __size);
#endif
-#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
- return ::operator delete(__ptr);
+ }
+
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+ static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) {
+#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+ ((void)__size);
+ return __do_call(__ptr, __align);
#else
- return __builtin_operator_delete(__ptr);
+ return __do_call(__ptr, __size, __align);
+#endif
+ }
#endif
-}
-#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
-_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_NO_EXCEPTIONS
-_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
+private:
+ template <class _A1, class _A2>
+ static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) {
+#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
+ defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
+ return ::operator delete(__ptr, __a1, __a2);
+#else
+ return __builtin_operator_delete(__ptr, __a1, __a2);
#endif
-void __throw_bad_array_length()
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw bad_array_length();
+ }
+
+ template <class _A1>
+ static inline void __do_call(void *__ptr, _A1 __a1) {
+#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
+ defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
+ return ::operator delete(__ptr, __a1);
#else
- _VSTD::abort();
+ return __builtin_operator_delete(__ptr, __a1);
#endif
-}
+ }
+
+ static inline void __do_call(void *__ptr) {
+#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
+ return ::operator delete(__ptr);
+#else
+ return __builtin_operator_delete(__ptr);
#endif
+ }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
+ _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
+ _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
+}
template <class _Tp>
-_LIBCPP_NODISCARD_AFTER_CXX17 inline
+_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
static_assert (!(is_function<_Tp>::value), "can't launder functions" );
diff --git a/include/numeric b/include/numeric
index b33b6a398eb0..4e68239d059e 100644
--- a/include/numeric
+++ b/include/numeric
@@ -104,15 +104,15 @@ template<class InputIterator, class OutputIterator, class T,
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation>
- OutputIterator
- transform_inclusive_scan(InputIterator first, InputIterator last,
+ OutputIterator
+ transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op, UnaryOperation unary_op); // C++17
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation, class T>
- OutputIterator
- transform_inclusive_scan(InputIterator first, InputIterator last,
+ OutputIterator
+ transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op, UnaryOperation unary_op,
T init); // C++17
@@ -142,6 +142,7 @@ template <class M, class N>
#include <iterator>
#include <limits> // for numeric_limits
#include <functional>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
diff --git a/include/optional b/include/optional
index a76f8d18976e..70422068e285 100644
--- a/include/optional
+++ b/include/optional
@@ -105,8 +105,8 @@ namespace std {
// 23.6.3.3, assignment
optional &operator=(nullopt_t) noexcept;
- optional &operator=(const optional &);
- optional &operator=(optional &&) noexcept(see below );
+ optional &operator=(const optional &); // constexpr in C++20
+ optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
template <class U = T> optional &operator=(U &&);
template <class U> optional &operator=(const optional<U> &);
template <class U> optional &operator=(optional<U> &&);
@@ -156,6 +156,7 @@ template<class T>
#include <stdexcept>
#include <type_traits>
#include <utility>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -168,7 +169,7 @@ _LIBCPP_PUSH_MACROS
namespace std // purposefully not using versioning namespace
{
-class _LIBCPP_EXCEPTION_ABI bad_optional_access
+class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public exception
{
public:
@@ -185,6 +186,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_NORETURN
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
void __throw_bad_optional_access() {
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_optional_access();
@@ -932,6 +934,7 @@ public:
using __base::__get;
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const&
{
if (!this->has_value())
@@ -940,6 +943,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type& value() &
{
if (!this->has_value())
@@ -948,6 +952,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type&& value() &&
{
if (!this->has_value())
@@ -956,6 +961,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type const&& value() const&&
{
if (!this->has_value())
diff --git a/include/ostream b/include/ostream
index 5404e0dca6c8..d700a369b34a 100644
--- a/include/ostream
+++ b/include/ostream
@@ -140,6 +140,7 @@ template <class charT, class traits, class T>
#include <locale>
#include <iterator>
#include <bitset>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -160,7 +161,7 @@ public:
typedef typename traits_type::off_type off_type;
// 27.7.2.2 Constructor/destructor:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
{ this->init(__sb); }
virtual ~basic_ostream();
@@ -173,7 +174,7 @@ protected:
inline _LIBCPP_INLINE_VISIBILITY
basic_ostream& operator=(basic_ostream&& __rhs);
#endif
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_ostream& __rhs)
{ basic_ios<char_type, traits_type>::swap(__rhs); }
@@ -190,16 +191,16 @@ public:
class _LIBCPP_TEMPLATE_VIS sentry;
// 27.7.2.6 Formatted output:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
{ return __pf(*this); }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(basic_ios<char_type, traits_type>&
(*__pf)(basic_ios<char_type,traits_type>&))
{ __pf(*this); return *this; }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(ios_base& (*__pf)(ios_base&))
{ __pf(*this); return *this; }
@@ -224,11 +225,11 @@ public:
basic_ostream& flush();
// 27.7.2.5 seeks:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
pos_type tellp();
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& seekp(pos_type __pos);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
protected:
@@ -1092,7 +1093,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
}
-#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
+#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>)
#endif
diff --git a/include/random b/include/random
index 89664a6ca331..724bd0fc2154 100644
--- a/include/random
+++ b/include/random
@@ -2337,7 +2337,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
for (size_t __i = 1; __i < __n; ++__i)
if (__x_[__i] != 0)
return;
- __x_[0] = _Max;
+ __x_[0] = result_type(1) << (__w - 1);
}
}
@@ -2363,7 +2363,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
for (size_t __i = 1; __i < __n; ++__i)
if (__x_[__i] != 0)
return;
- __x_[0] = _Max;
+ __x_[0] = result_type(1) << (__w - 1);
}
}
diff --git a/include/regex b/include/regex
index 84aacc029edc..bd83d7c10ca7 100644
--- a/include/regex
+++ b/include/regex
@@ -769,6 +769,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#include <memory>
#include <vector>
#include <deque>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -989,6 +990,10 @@ public:
#if defined(__mips__) && defined(__GLIBC__)
static const char_class_type __regex_word = static_cast<char_class_type>(_ISbit(15));
+#elif defined(__NetBSD__)
+ // NetBSD defines classes up to 0x2000
+ // see sys/ctype_bits.h, _CTYPE_Q
+ static const char_class_type __regex_word = 0x8000;
#else
static const char_class_type __regex_word = 0x80;
#endif
@@ -1351,9 +1356,9 @@ public:
virtual ~__node() {}
_LIBCPP_INLINE_VISIBILITY
- virtual void __exec(__state&) const {};
+ virtual void __exec(__state&) const {}
_LIBCPP_INLINE_VISIBILITY
- virtual void __exec_split(bool, __state&) const {};
+ virtual void __exec_split(bool, __state&) const {}
};
// __end_state
@@ -2414,20 +2419,17 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
goto __exit;
}
}
- // set of "__found" chars =
+ // When there's at least one of __neg_chars_ and __neg_mask_, the set
+ // of "__found" chars is
// union(complement(union(__neg_chars_, __neg_mask_)),
// other cases...)
//
- // __neg_chars_ and __neg_mask_'d better be handled together, as there
- // are no short circuit opportunities.
- //
- // In addition, when __neg_mask_/__neg_chars_ is empty, they should be
- // treated as all ones/all chars.
+ // It doesn't make sense to check this when there are no __neg_chars_
+ // and no __neg_mask_.
+ if (!(__neg_mask_ == 0 && __neg_chars_.empty()))
{
- const bool __in_neg_mask = (__neg_mask_ == 0) ||
- __traits_.isctype(__ch, __neg_mask_);
+ const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_);
const bool __in_neg_chars =
- __neg_chars_.empty() ||
std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=
__neg_chars_.end();
if (!(__in_neg_mask || __in_neg_chars))
diff --git a/include/scoped_allocator b/include/scoped_allocator
index 4760d946def7..bdbb0136b5c3 100644
--- a/include/scoped_allocator
+++ b/include/scoped_allocator
@@ -108,6 +108,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
#include <__config>
#include <memory>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
diff --git a/include/set b/include/set
index 108a9e97f88d..a0155f0b2758 100644
--- a/include/set
+++ b/include/set
@@ -128,6 +128,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class C2>
+ void merge(set<Key, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(set<Key, C2, Allocator>&& source); // C++17
+ template<class C2>
+ void merge(multiset<Key, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(multiset<Key, C2, Allocator>&& source); // C++17
+
void swap(set& s)
noexcept(
__is_nothrow_swappable<key_compare>::value &&
@@ -207,6 +216,9 @@ void
swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class Key, class Compare, class Allocator, class Predicate>
+ void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
+
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key>>
class multiset
@@ -316,6 +328,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class C2>
+ void merge(multiset<Key, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(multiset<Key, C2, Allocator>&& source); // C++17
+ template<class C2>
+ void merge(set<Key, C2, Allocator>& source); // C++17
+ template<class C2>
+ void merge(set<Key, C2, Allocator>&& source); // C++17
+
void swap(multiset& s)
noexcept(
__is_nothrow_swappable<key_compare>::value &&
@@ -394,6 +415,9 @@ void
swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class Key, class Compare, class Allocator, class Predicate>
+ void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -402,6 +426,7 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
#include <__tree>
#include <__node_handle>
#include <functional>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -409,6 +434,9 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Key, class _Compare, class _Allocator>
+class multiset;
+
template <class _Key, class _Compare = less<_Key>,
class _Allocator = allocator<_Key> >
class _LIBCPP_TEMPLATE_VIS set
@@ -423,6 +451,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
+ static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@@ -448,6 +477,11 @@ public:
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
+ template <class _Key2, class _Compare2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS set;
+ template <class _Key2, class _Compare2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS multiset;
+
_LIBCPP_INLINE_VISIBILITY
set()
_NOEXCEPT_(
@@ -486,7 +520,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <class _InputIterator>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
: set(__f, __l, key_compare(), __a) {}
#endif
@@ -542,7 +576,7 @@ public:
}
#if _LIBCPP_STD_VER > 11
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
set(initializer_list<value_type> __il, const allocator_type& __a)
: set(__il, key_compare(), __a) {}
#endif
@@ -680,6 +714,38 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(set<key_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(set<key_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multiset<key_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_unique(__source.__tree_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -852,6 +918,13 @@ swap(set<_Key, _Compare, _Allocator>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Compare, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
template <class _Key, class _Compare = less<_Key>,
class _Allocator = allocator<_Key> >
class _LIBCPP_TEMPLATE_VIS multiset
@@ -866,6 +939,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
+ static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@@ -890,6 +964,11 @@ public:
typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
#endif
+ template <class _Key2, class _Compare2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS set;
+ template <class _Key2, class _Compare2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS multiset;
+
// construct/copy/destroy:
_LIBCPP_INLINE_VISIBILITY
multiset()
@@ -920,7 +999,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <class _InputIterator>
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
: multiset(__f, __l, key_compare(), __a) {}
#endif
@@ -984,7 +1063,7 @@ public:
}
#if _LIBCPP_STD_VER > 11
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY
multiset(initializer_list<value_type> __il, const allocator_type& __a)
: multiset(__il, key_compare(), __a) {}
#endif
@@ -1121,6 +1200,38 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multiset<key_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(set<key_type, _Compare2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
+ template <class _Compare2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(set<key_type, _Compare2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __tree_.__node_handle_merge_multi(__source.__tree_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -1294,6 +1405,13 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Compare, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_SET
diff --git a/include/shared_mutex b/include/shared_mutex
index a7735d6732c5..3daf74d26c74 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -124,6 +124,7 @@ template <class Mutex>
*/
#include <__config>
+#include <version>
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
@@ -143,7 +144,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base
+struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex"))
+__shared_mutex_base
{
mutex __mut_;
condition_variable __gate1_;
@@ -160,14 +162,14 @@ struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base
__shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
// Exclusive ownership
- void lock(); // blocking
- bool try_lock();
- void unlock();
+ void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking
+ bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
+ void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
// Shared ownership
- void lock_shared(); // blocking
- bool try_lock_shared();
- void unlock_shared();
+ void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking
+ bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true));
+ void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability());
// typedef implementation-defined native_handle_type; // See 30.2.3
// native_handle_type native_handle(); // See 30.2.3
diff --git a/include/span b/include/span
index db8f836f9184..cebe98760f27 100644
--- a/include/span
+++ b/include/span
@@ -23,27 +23,13 @@ inline constexpr ptrdiff_t dynamic_extent = -1;
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span;
-// [span.comparison], span comparison operators
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator==(span<T, X> l, span<U, Y> r);
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator!=(span<T, X> l, span<U, Y> r);
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator<(span<T, X> l, span<U, Y> r);
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator<=(span<T, X> l, span<U, Y> r);
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator>(span<T, X> l, span<U, Y> r);
-template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
- constexpr bool operator>=(span<T, X> l, span<U, Y> r);
-
// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
- span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
+ span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
template <class ElementType, ptrdiff_t Extent>
- span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
+ span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
@@ -123,7 +109,7 @@ private:
template<class T, size_t N>
span(T (&)[N]) -> span<T, N>;
-
+
template<class T, size_t N>
span(array<T, N>&) -> span<T, N>;
@@ -194,8 +180,8 @@ struct __is_span_compatible_container<_Tp, _ElementType,
decltype(size(declval<_Tp>())),
// remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[]
typename enable_if<
- is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
- _ElementType(*)[]>,
+ is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
+ _ElementType(*)[]>,
nullptr_t>::type
>>
: public true_type {};
@@ -221,7 +207,7 @@ public:
static constexpr index_type extent = _Extent;
static_assert (_Extent >= 0, "Can't have a span with an extent < 0");
-// [span.cons], span constructors, copy, assignment, and destructor
+// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
{ static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
@@ -242,7 +228,7 @@ public:
constexpr span( _Container& __c,
enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}
- { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container))"); }
+ { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container)"); }
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
@@ -287,7 +273,7 @@ public:
static_assert(_Count <= _Extent, "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
-
+
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
{
@@ -315,7 +301,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent>
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
- {
+ {
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
@@ -331,14 +317,14 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
- return __data[__idx];
- }
+ return __data[__idx];
+ }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>() index out of bounds");
- return __data[__idx];
- }
+ return __data[__idx];
+ }
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
@@ -358,7 +344,7 @@ public:
__data = __other.__data;
__other.__data = __p;
}
-
+
_LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
@@ -392,7 +378,7 @@ public:
static constexpr index_type extent = dynamic_extent;
-// [span.cons], span constructors, copy, assignment, and destructor
+// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
constexpr span (const span&) noexcept = default;
@@ -408,7 +394,7 @@ public:
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
-
+
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
@@ -440,7 +426,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
- static_assert(_Count >= 0);
+ static_assert(_Count >= 0, "Count must be >= 0 in span::first()");
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
return {data(), _Count};
}
@@ -449,7 +435,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
- static_assert(_Count >= 0);
+ static_assert(_Count >= 0, "Count must be >= 0 in span::last()");
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
@@ -460,7 +446,7 @@ public:
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)");
return {data(), __count};
}
-
+
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept
{
@@ -480,7 +466,7 @@ public:
constexpr span<element_type, dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
- {
+ {
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
@@ -496,14 +482,14 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
- return __data[__idx];
- }
+ return __data[__idx];
+ }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>() index out of bounds");
- return __data[__idx];
- }
+ return __data[__idx];
+ }
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
@@ -539,39 +525,9 @@ private:
index_type __size;
};
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
-
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator!=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return !(__rhs == __lhs); }
-
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator< (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return lexicographical_compare (__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
-
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator<=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return !(__rhs < __lhs); }
-
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator> (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return __rhs < __lhs; }
-
-template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
- constexpr bool
- operator>=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
- { return !(__lhs < __rhs); }
-
// as_bytes & as_writeable_bytes
template <class _Tp, ptrdiff_t _Extent>
- auto as_bytes(span<_Tp, _Extent> __s) noexcept
+ auto as_bytes(span<_Tp, _Extent> __s) noexcept
-> decltype(__s.__as_bytes())
{ return __s.__as_bytes(); }
@@ -588,7 +544,7 @@ template <class _Tp, ptrdiff_t _Extent>
// Deduction guides
template<class _Tp, size_t _Sz>
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
-
+
template<class _Tp, size_t _Sz>
span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;
diff --git a/include/sstream b/include/sstream
index b01f47b6872c..9c3ee13bfbad 100644
--- a/include/sstream
+++ b/include/sstream
@@ -473,12 +473,12 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
{
while (__sz > INT_MAX)
{
- this->pbump(INT_MAX);
- __sz -= INT_MAX;
+ this->pbump(INT_MAX);
+ __sz -= INT_MAX;
}
if (__sz > 0)
- this->pbump(__sz);
- }
+ this->pbump(__sz);
+ }
}
}
diff --git a/include/stddef.h b/include/stddef.h
index faf8552d8ce7..f65065d869a8 100644
--- a/include/stddef.h
+++ b/include/stddef.h
@@ -54,7 +54,7 @@ using std::nullptr_t;
// Re-use the compiler's <stddef.h> max_align_t where possible.
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \
- !defined(__DEFINED_max_align_t)
+ !defined(__DEFINED_max_align_t) && !defined(__NetBSD__)
typedef long double max_align_t;
#endif
diff --git a/include/stdexcept b/include/stdexcept
index 6533497e4ea5..3ec79349aa92 100644
--- a/include/stdexcept
+++ b/include/stdexcept
@@ -192,7 +192,7 @@ void __throw_logic_error(const char*__msg)
throw logic_error(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -203,7 +203,7 @@ void __throw_domain_error(const char*__msg)
throw domain_error(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -214,7 +214,7 @@ void __throw_invalid_argument(const char*__msg)
throw invalid_argument(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -225,7 +225,7 @@ void __throw_length_error(const char*__msg)
throw length_error(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -236,7 +236,7 @@ void __throw_out_of_range(const char*__msg)
throw out_of_range(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
@@ -247,7 +247,7 @@ void __throw_range_error(const char*__msg)
throw range_error(__msg);
#else
((void)__msg);
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
diff --git a/include/streambuf b/include/streambuf
index 37a653237161..dd293dc639b9 100644
--- a/include/streambuf
+++ b/include/streambuf
@@ -138,7 +138,7 @@ public:
virtual ~basic_streambuf();
// 27.6.2.2.1 locales:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
locale pubimbue(const locale& __loc) {
imbue(__loc);
locale __r = __loc_;
@@ -146,70 +146,70 @@ public:
return __r;
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
locale getloc() const { return __loc_; }
// 27.6.2.2.2 buffer and positioning:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_streambuf* pubsetbuf(char_type* __s, streamsize __n)
{ return setbuf(__s, __n); }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
pos_type pubseekoff(off_type __off, ios_base::seekdir __way,
ios_base::openmode __which = ios_base::in | ios_base::out)
{ return seekoff(__off, __way, __which); }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
pos_type pubseekpos(pos_type __sp,
ios_base::openmode __which = ios_base::in | ios_base::out)
{ return seekpos(__sp, __which); }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int pubsync() { return sync(); }
// Get and put areas:
// 27.6.2.2.3 Get area:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
streamsize in_avail() {
if (__ninp_ < __einp_)
return static_cast<streamsize>(__einp_ - __ninp_);
return showmanyc();
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type snextc() {
if (sbumpc() == traits_type::eof())
return traits_type::eof();
return sgetc();
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type sbumpc() {
if (__ninp_ == __einp_)
return uflow();
return traits_type::to_int_type(*__ninp_++);
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type sgetc() {
if (__ninp_ == __einp_)
return underflow();
return traits_type::to_int_type(*__ninp_);
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
streamsize sgetn(char_type* __s, streamsize __n)
{ return xsgetn(__s, __n); }
// 27.6.2.2.4 Putback:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type sputbackc(char_type __c) {
if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
return pbackfail(traits_type::to_int_type(__c));
return traits_type::to_int_type(*--__ninp_);
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type sungetc() {
if (__binp_ == __ninp_)
return pbackfail();
@@ -217,7 +217,7 @@ public:
}
// 27.6.2.2.5 Put area:
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
int_type sputc(char_type __c) {
if (__nout_ == __eout_)
return overflow(traits_type::to_int_type(__c));
@@ -225,7 +225,7 @@ public:
return traits_type::to_int_type(__c);
}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
streamsize sputn(const char_type* __s, streamsize __n)
{ return xsputn(__s, __n); }
@@ -240,10 +240,10 @@ protected:
_LIBCPP_INLINE_VISIBILITY char_type* gptr() const {return __ninp_;}
_LIBCPP_INLINE_VISIBILITY char_type* egptr() const {return __einp_;}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void gbump(int __n) { __ninp_ += __n; }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
__binp_ = __gbeg;
__ninp_ = __gnext;
@@ -255,13 +255,13 @@ protected:
_LIBCPP_INLINE_VISIBILITY char_type* pptr() const {return __nout_;}
_LIBCPP_INLINE_VISIBILITY char_type* epptr() const {return __eout_;}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void pbump(int __n) { __nout_ += __n; }
_LIBCPP_INLINE_VISIBILITY
void __pbump(streamsize __n) { __nout_ += __n; }
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void setp(char_type* __pbeg, char_type* __pend) {
__bout_ = __nout_ = __pbeg;
__eout_ = __pend;
@@ -486,7 +486,7 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type)
return traits_type::eof();
}
-#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
+#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>)
diff --git a/include/string b/include/string
index 162e54058c42..fb838d1e5dd2 100644
--- a/include/string
+++ b/include/string
@@ -437,6 +437,11 @@ template<class charT, class traits, class Allocator>
basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
+template<class charT, class traits, class Allocator, class U>
+void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
+template<class charT, class traits, class Allocator, class Predicate>
+void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
+
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;
@@ -510,6 +515,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1
#include <type_traits>
#include <initializer_list>
#include <__functional_base>
+#include <version>
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
#include <cstdint>
#endif
@@ -579,6 +585,7 @@ basic_string<_CharT, _Traits, _Allocator>
operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
@@ -806,7 +813,9 @@ public:
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+#endif
_LIBCPP_INLINE_VISIBILITY
basic_string(const _CharT* __s) {
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
@@ -816,7 +825,9 @@ public:
# endif
}
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+#endif
_LIBCPP_INLINE_VISIBILITY
basic_string(const _CharT* __s, const _Allocator& __a);
@@ -827,7 +838,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, _CharT __c);
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
+#endif
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, _CharT __c, const _Allocator& __a);
@@ -948,7 +961,11 @@ public:
void resize(size_type __n, value_type __c);
_LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
- void reserve(size_type __res_arg = 0);
+ void reserve(size_type __res_arg);
+ _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n);
+
+ _LIBCPP_INLINE_VISIBILITY
+ void reserve() _NOEXCEPT {reserve(0);}
_LIBCPP_INLINE_VISIBILITY
void shrink_to_fit() _NOEXCEPT {reserve();}
_LIBCPP_INLINE_VISIBILITY
@@ -1002,6 +1019,10 @@ public:
basic_string& append(const value_type* __s, size_type __n);
basic_string& append(const value_type* __s);
basic_string& append(size_type __n, value_type __c);
+
+ _LIBCPP_INLINE_VISIBILITY
+ void __append_default_init(size_type __n);
+
template <class _ForwardIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
@@ -1664,7 +1685,7 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
{
@@ -1674,7 +1695,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1704,7 +1725,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
{
@@ -1715,7 +1736,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
@@ -1780,7 +1801,9 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
}
template <class _CharT, class _Traits, class _Allocator>
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template <class>
+#endif
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
: __r_(__second_tag(), __a)
{
@@ -1792,7 +1815,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
@@ -1803,7 +1826,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
: __r_(__second_tag(), __a)
{
@@ -1844,7 +1867,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
@@ -1862,7 +1885,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
: __r_(__second_tag(), __a)
{
@@ -1907,7 +1930,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
{
__init(__n, __c);
@@ -1917,7 +1940,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __
}
template <class _CharT, class _Traits, class _Allocator>
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template <class>
+#endif
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
: __r_(__second_tag(), __a)
{
@@ -1943,7 +1968,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
const _Allocator& __a)
: __r_(__second_tag(), __a)
@@ -2054,7 +2079,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
{
__init(__first, __last);
@@ -2065,7 +2090,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first,
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: __r_(__second_tag(), __a)
@@ -2079,7 +2104,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first,
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il)
{
@@ -2090,7 +2115,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il, const _Allocator& __a)
@@ -2254,7 +2279,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
_NOEXCEPT_(__alloc_traits::is_always_equal::value)
@@ -2266,7 +2291,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, fa
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
#if _LIBCPP_STD_VER > 14
@@ -2282,7 +2307,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
@@ -2416,6 +2441,23 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
+inline void
+basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n)
+{
+ if (__n)
+ {
+ size_type __cap = capacity();
+ size_type __sz = size();
+ if (__cap - __sz < __n)
+ __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+ pointer __p = __get_pointer();
+ __sz += __n;
+ __set_size(__sz);
+ traits_type::assign(__p[__sz], value_type());
+ }
+}
+
+template <class _CharT, class _Traits, class _Allocator>
void
basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
{
@@ -2499,7 +2541,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe(
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
{
@@ -2676,7 +2718,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
{
@@ -2746,7 +2788,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
{
@@ -2866,7 +2908,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
{
@@ -2910,7 +2952,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
{
@@ -2919,7 +2961,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
{
@@ -2927,7 +2969,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
{
@@ -2935,7 +2977,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
{
@@ -2967,7 +3009,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
{
@@ -2985,7 +3027,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
{
@@ -3002,7 +3044,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_i
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::pop_back()
{
@@ -3024,7 +3066,7 @@ basic_string<_CharT, _Traits, _Allocator>::pop_back()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
{
@@ -3042,7 +3084,7 @@ basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
{
@@ -3071,7 +3113,18 @@ basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline void
+basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n)
+{
+ size_type __sz = size();
+ if (__n > __sz) {
+ __append_default_init(__n - __sz);
+ } else
+ __erase_to_end(__n);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
{
@@ -3147,7 +3200,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
{
@@ -3156,7 +3209,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NO
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
{
@@ -3183,7 +3236,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::front()
{
@@ -3192,7 +3245,7 @@ basic_string<_CharT, _Traits, _Allocator>::front()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::front() const
{
@@ -3201,7 +3254,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() const
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::back()
{
@@ -3210,7 +3263,7 @@ basic_string<_CharT, _Traits, _Allocator>::back()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::back() const
{
@@ -3231,7 +3284,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n,
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
basic_string<_CharT, _Traits, _Allocator>
basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
{
@@ -3239,7 +3292,7 @@ basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
#if _LIBCPP_STD_VER >= 14
@@ -3287,7 +3340,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3312,7 +3365,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3345,7 +3398,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3370,7 +3423,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3403,7 +3456,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3428,7 +3481,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3439,7 +3492,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3461,7 +3514,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3486,7 +3539,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3497,7 +3550,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3519,7 +3572,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3544,7 +3597,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3555,7 +3608,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3578,7 +3631,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
size_type __pos) const _NOEXCEPT
@@ -3603,7 +3656,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
size_type __pos) const _NOEXCEPT
@@ -3614,7 +3667,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __
}
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
size_type __pos) const _NOEXCEPT
@@ -3649,7 +3702,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
int
basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
{
@@ -3695,7 +3748,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
int
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
@@ -3753,7 +3806,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
// __invariants
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
bool
basic_string<_CharT, _Traits, _Allocator>::__invariants() const
{
@@ -3771,7 +3824,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const
// __clear_and_shrink
template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline
void
basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
{
@@ -4025,6 +4078,7 @@ operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
}
template<class _CharT, class _Traits, class _Allocator>
+inline
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
{
@@ -4121,11 +4175,13 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
__lhs.swap(__rhs);
}
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+typedef basic_string<char8_t> u8string;
+#endif
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
-
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10);
@@ -4225,6 +4281,18 @@ getline(basic_istream<_CharT, _Traits>&& __is,
#endif // _LIBCPP_CXX03_LANG
+#if _LIBCPP_STD_VER > 17
+template<class _CharT, class _Traits, class _Allocator, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v)
+{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); }
+
+template<class _CharT, class _Traits, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred)
+{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); }
+#endif
+
#if _LIBCPP_DEBUG_LEVEL >= 2
template<class _CharT, class _Traits, class _Allocator>
@@ -4282,6 +4350,14 @@ inline namespace literals
return basic_string<wchar_t> (__str, __len);
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ inline _LIBCPP_INLINE_VISIBILITY
+ basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
+ {
+ return basic_string<char8_t> (__str, __len);
+ }
+#endif
+
inline _LIBCPP_INLINE_VISIBILITY
basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
{
diff --git a/include/string_view b/include/string_view
index 6377aeb6d648..7d783122f123 100644
--- a/include/string_view
+++ b/include/string_view
@@ -178,6 +178,7 @@ namespace std {
#include <iterator>
#include <limits>
#include <stdexcept>
+#include <version>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -768,6 +769,9 @@ bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type
}
typedef basic_string_view<char> string_view;
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+typedef basic_string_view<char8_t> u8string_view;
+#endif
typedef basic_string_view<char16_t> u16string_view;
typedef basic_string_view<char32_t> u32string_view;
typedef basic_string_view<wchar_t> wstring_view;
@@ -777,17 +781,12 @@ template<class _CharT, class _Traits>
struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
: public unary_function<basic_string_view<_CharT, _Traits>, size_t>
{
- size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT;
+ _LIBCPP_INLINE_VISIBILITY
+ size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT {
+ return __do_string_hash(__val.data(), __val.data() + __val.size());
+ }
};
-template<class _CharT, class _Traits>
-size_t
-hash<basic_string_view<_CharT, _Traits> >::operator()(
- const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT
-{
- return __do_string_hash(__val.data(), __val.data() + __val.size());
-}
-
#if _LIBCPP_STD_VER > 11
inline namespace literals
@@ -806,6 +805,14 @@ inline namespace literals
return basic_string_view<wchar_t> (__str, __len);
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+ basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
+ {
+ return basic_string_view<char8_t> (__str, __len);
+ }
+#endif
+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
{
diff --git a/include/support/win32/locale_win32.h b/include/support/win32/locale_win32.h
index 68682c9624b8..c7c6d786cb83 100644
--- a/include/support/win32/locale_win32.h
+++ b/include/support/win32/locale_win32.h
@@ -35,8 +35,8 @@ public:
: __locale(nullptr), __locale_str(nullptr) {}
locale_t(std::nullptr_t)
: __locale(nullptr), __locale_str(nullptr) {}
- locale_t(_locale_t __locale, const char* __locale_str)
- : __locale(__locale), __locale_str(__locale_str) {}
+ locale_t(_locale_t __xlocale, const char* __xlocale_str)
+ : __locale(__xlocale), __locale_str(__xlocale_str) {}
friend bool operator==(const locale_t& __left, const locale_t& __right) {
return __left.__locale == __right.__locale;
diff --git a/include/thread b/include/thread
index 0629d70efda4..8c0115f8708d 100644
--- a/include/thread
+++ b/include/thread
@@ -151,7 +151,7 @@ class __thread_specific_ptr
__thread_specific_ptr(const __thread_specific_ptr&);
__thread_specific_ptr& operator=(const __thread_specific_ptr&);
- static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+ _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
public:
typedef _Tp* pointer;
diff --git a/include/tuple b/include/tuple
index b3a17e7b7354..4cc69030b9ab 100644
--- a/include/tuple
+++ b/include/tuple
@@ -65,7 +65,7 @@ public:
template <class U1, class U2>
tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
template <class U1, class U2>
- tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
+ tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2
void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
};
@@ -84,8 +84,8 @@ template <class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t); // C++17
// 20.4.1.4, tuple helper classes:
-template <class T> class tuple_size; // undefined
-template <class... T> class tuple_size<tuple<T...>>;
+template <class T> struct tuple_size; // undefined
+template <class... T> struct tuple_size<tuple<T...>>;
template <class T>
inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
template <size_t I, class T> class tuple_element; // undefined
@@ -141,6 +141,7 @@ template <class... Types>
#include <type_traits>
#include <__functional_base>
#include <utility>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -1077,30 +1078,12 @@ namespace {
_LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
}
-template <class _Tp>
-struct __make_tuple_return_impl
-{
- typedef _Tp type;
-};
-
-template <class _Tp>
-struct __make_tuple_return_impl<reference_wrapper<_Tp> >
-{
- typedef _Tp& type;
-};
-
-template <class _Tp>
-struct __make_tuple_return
-{
- typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
-};
-
template <class... _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-tuple<typename __make_tuple_return<_Tp>::type...>
+tuple<typename __unwrap_ref_decay<_Tp>::type...>
make_tuple(_Tp&&... __t)
{
- return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
+ return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
}
template <class... _Tp>
diff --git a/include/type_traits b/include/type_traits
index 30bfb161c0d4..8b30511a4ecb 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -75,6 +75,10 @@ namespace std
template <class T> struct remove_pointer;
template <class T> struct add_pointer;
+ template<class T> struct type_identity; // C++20
+ template<class T>
+ using type_identity_t = typename type_identity<T>::type; // C++20
+
// Integral properties:
template <class T> struct is_signed;
template <class T> struct is_unsigned;
@@ -400,6 +404,7 @@ namespace std
*/
#include <__config>
#include <cstddef>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -704,6 +709,9 @@ template <> struct __libcpp_is_integral<char> : public tr
template <> struct __libcpp_is_integral<signed char> : public true_type {};
template <> struct __libcpp_is_integral<unsigned char> : public true_type {};
template <> struct __libcpp_is_integral<wchar_t> : public true_type {};
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+template <> struct __libcpp_is_integral<char8_t> : public true_type {};
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <> struct __libcpp_is_integral<char16_t> : public true_type {};
template <> struct __libcpp_is_integral<char32_t> : public true_type {};
@@ -733,12 +741,6 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
// is_floating_point
template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
-#ifdef __clang__
-template <> struct __libcpp_is_floating_point<__fp16> : public true_type {};
-#endif
-#ifdef __FLT16_MANT_DIG__
-template <> struct __libcpp_is_floating_point<_Float16> : public true_type {};
-#endif
template <> struct __libcpp_is_floating_point<float> : public true_type {};
template <> struct __libcpp_is_floating_point<double> : public true_type {};
template <> struct __libcpp_is_floating_point<long double> : public true_type {};
@@ -1226,6 +1228,12 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer
template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
#endif
+// type_identity
+#if _LIBCPP_STD_VER > 17
+template<class _Tp> struct type_identity { typedef _Tp type; };
+template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
+#endif
+
// is_signed
template <class _Tp, bool = is_integral<_Tp>::value>
@@ -1644,7 +1652,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool has_unique_object_representations_v
// alignment_of
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
- : public integral_constant<size_t, __alignof__(_Tp)> {};
+ : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
@@ -1674,7 +1682,7 @@ struct __nat
template <class _Tp>
struct __align_type
{
- static const size_t value = alignment_of<_Tp>::value;
+ static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
typedef _Tp type;
};
@@ -1807,8 +1815,8 @@ struct __static_max<_I0, _I1, _In...>
template <size_t _Len, class _Type0, class ..._Types>
struct aligned_union
{
- static const size_t alignment_value = __static_max<__alignof__(_Type0),
- __alignof__(_Types)...>::value;
+ static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
+ _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
static const size_t __len = __static_max<_Len, sizeof(_Type0),
sizeof(_Types)...>::value;
typedef typename aligned_storage<__len, alignment_value>::type type;
@@ -4748,7 +4756,6 @@ struct __has_operator_addressof
#if _LIBCPP_STD_VER > 14
-#define __cpp_lib_void_t 201411
template <class...> using void_t = void;
# ifndef _LIBCPP_HAS_NO_VARIADICS
diff --git a/include/typeinfo b/include/typeinfo
index f32ea6e76f17..8411532860bd 100644
--- a/include/typeinfo
+++ b/include/typeinfo
@@ -73,12 +73,8 @@ public:
#include <vcruntime_typeinfo.h>
#else
-#if !defined(_LIBCPP_ABI_MICROSOFT)
-#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
-#define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
-#else
-#define _LIBCPP_HAS_UNIQUE_TYPEINFO
-#endif
+#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) && !defined(_LIBCPP_ABI_MICROSOFT)
+# define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
#endif
namespace std // purposefully not using versioning namespace
@@ -232,7 +228,7 @@ void __throw_bad_cast()
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_cast();
#else
- _VSTD::abort();
+ _VSTD::abort();
#endif
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/unordered_map b/include/unordered_map
index 348f57923b52..6035b05dc61c 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -153,6 +153,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class H2, class P2>
+ void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17
+
void swap(unordered_map&)
noexcept(
(!allocator_type::propagate_on_container_swap::value ||
@@ -325,6 +334,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class H2, class P2>
+ void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17
+
void swap(unordered_multimap&)
noexcept(
(!allocator_type::propagate_on_container_swap::value ||
@@ -366,6 +384,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
noexcept(noexcept(x.swap(y)));
+template <class K, class T, class H, class P, class A, class Predicate>
+ void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
+
+template <class K, class T, class H, class P, class A, class Predicate>
+ void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
+
template <class Key, class T, class Hash, class Pred, class Alloc>
bool
operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
@@ -386,6 +410,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#include <functional>
#include <stdexcept>
#include <tuple>
+#include <version>
#include <__debug>
@@ -395,7 +420,8 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Key, class _Cp, class _Hash, bool _IsEmpty>
+template <class _Key, class _Cp, class _Hash,
+ bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
class __unordered_map_hasher
: private _Hash
{
@@ -463,7 +489,8 @@ swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x,
__x.swap(__y);
}
-template <class _Key, class _Cp, class _Pred, bool _IsEmpty>
+template <class _Key, class _Cp, class _Pred,
+ bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value>
class __unordered_map_equal
: private _Pred
{
@@ -807,6 +834,9 @@ public:
template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
};
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+class unordered_multimap;
+
template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
class _Alloc = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_TEMPLATE_VIS unordered_map
@@ -823,6 +853,7 @@ public:
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
"Invalid allocator::value_type");
+ static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
private:
typedef __hash_value_type<key_type, mapped_type> __value_type;
@@ -864,6 +895,11 @@ public:
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
+ template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_map;
+ template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
+
_LIBCPP_INLINE_VISIBILITY
unordered_map()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1187,6 +1223,39 @@ public:
return __table_.template __node_handle_extract<node_type>(
__it.__i_);
}
+
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_unique(__source.__table_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -1563,6 +1632,13 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
bool
operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
@@ -1607,6 +1683,7 @@ public:
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
"Invalid allocator::value_type");
+ static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), "");
private:
typedef __hash_value_type<key_type, mapped_type> __value_type;
@@ -1645,6 +1722,11 @@ public:
typedef __map_node_handle<__node, allocator_type> node_type;
#endif
+ template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_map;
+ template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
+
_LIBCPP_INLINE_VISIBILITY
unordered_multimap()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1846,6 +1928,39 @@ public:
return __table_.template __node_handle_extract<node_type>(
__it.__i_);
}
+
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -2141,6 +2256,13 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
bool
operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
diff --git a/include/unordered_set b/include/unordered_set
index 9b8560da494a..b4e61da89eec 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -127,6 +127,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class H2, class P2>
+ void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17
+
void swap(unordered_set&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
@@ -282,6 +291,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
+ template<class H2, class P2>
+ void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17
+ template<class H2, class P2>
+ void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17
+
void swap(unordered_multiset&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
@@ -321,6 +339,13 @@ template <class Value, class Hash, class Pred, class Alloc>
unordered_multiset<Value, Hash, Pred, Alloc>& y)
noexcept(noexcept(x.swap(y)));
+template <class K, class T, class H, class P, class A, class Predicate>
+ void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
+
+template <class K, class T, class H, class P, class A, class Predicate>
+ void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
+
+
template <class Value, class Hash, class Pred, class Alloc>
bool
operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
@@ -338,6 +363,7 @@ template <class Value, class Hash, class Pred, class Alloc>
#include <__hash_table>
#include <__node_handle>
#include <functional>
+#include <version>
#include <__debug>
@@ -347,6 +373,9 @@ template <class Value, class Hash, class Pred, class Alloc>
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+class unordered_multiset;
+
template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
class _Alloc = allocator<_Value> >
class _LIBCPP_TEMPLATE_VIS unordered_set
@@ -362,6 +391,7 @@ public:
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
"Invalid allocator::value_type");
+ static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
private:
typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
@@ -384,6 +414,11 @@ public:
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
+ template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_set;
+ template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_multiset;
+
_LIBCPP_INLINE_VISIBILITY
unordered_set()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -589,6 +624,39 @@ public:
{
return __table_.template __node_handle_extract<node_type>(__it);
}
+
+ template<class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template<class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template<class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __table_.__node_handle_merge_unique(__source.__table_);
+ }
+ template<class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ __table_.__node_handle_merge_unique(__source.__table_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -873,6 +941,13 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
template <class _Value, class _Hash, class _Pred, class _Alloc>
bool
operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
@@ -916,6 +991,7 @@ public:
typedef const value_type& const_reference;
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
"Invalid allocator::value_type");
+ static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
private:
typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
@@ -937,6 +1013,11 @@ public:
typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
#endif
+ template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_set;
+ template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
+ friend class _LIBCPP_TEMPLATE_VIS unordered_multiset;
+
_LIBCPP_INLINE_VISIBILITY
unordered_multiset()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1101,6 +1182,39 @@ public:
{
return __table_.template __node_handle_extract<node_type>(__key);
}
+
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
+ template <class _H2, class _P2>
+ _LIBCPP_INLINE_VISIBILITY
+ void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
+ {
+ _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
+ "merging container with incompatible allocator");
+ return __table_.__node_handle_merge_multi(__source.__table_);
+ }
#endif
_LIBCPP_INLINE_VISIBILITY
@@ -1397,6 +1511,13 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
+{ __libcpp_erase_if_container(__c, __pred); }
+#endif
+
template <class _Value, class _Hash, class _Pred, class _Alloc>
bool
operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
diff --git a/include/utility b/include/utility
index ed9bf030d499..74bbc5cf34f9 100644
--- a/include/utility
+++ b/include/utility
@@ -103,7 +103,7 @@ swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
struct piecewise_construct_t { };
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
-template <class T> class tuple_size;
+template <class T> struct tuple_size;
template <size_t I, class T> class tuple_element;
template <class T1, class T2> struct tuple_size<pair<T1, T2> >;
@@ -203,6 +203,7 @@ template <size_t I>
#include <cstddef>
#include <cstring>
#include <cstdint>
+#include <version>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -296,12 +297,13 @@ template <class _Tp> void as_const(const _Tp&&) = delete;
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
-extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
+extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
#else
/* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
#endif
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
+template <class, class>
struct __non_trivially_copyable_base {
_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
__non_trivially_copyable_base() _NOEXCEPT {}
@@ -313,7 +315,7 @@ struct __non_trivially_copyable_base {
template <class _T1, class _T2>
struct _LIBCPP_TEMPLATE_VIS pair
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
-: private __non_trivially_copyable_base
+: private __non_trivially_copyable_base<_T1, _T2>
#endif
{
typedef _T1 first_type;
@@ -408,13 +410,17 @@ struct _LIBCPP_TEMPLATE_VIS pair
_CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>()
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
- pair() : first(), second() {}
+ pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
+ is_nothrow_default_constructible<second_type>::value)
+ : first(), second() {}
template <bool _Dummy = true, _EnableB<
_CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit pair(_T1 const& __t1, _T2 const& __t2)
+ _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
+ is_nothrow_copy_constructible<second_type>::value)
: first(__t1), second(__t2) {}
template<bool _Dummy = true, _EnableB<
@@ -422,6 +428,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair(_T1 const& __t1, _T2 const& __t2)
+ _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
+ is_nothrow_copy_constructible<second_type>::value)
: first(__t1), second(__t2) {}
template<class _U1, class _U2, _EnableB<
@@ -429,6 +437,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit pair(_U1&& __u1, _U2&& __u2)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
+ is_nothrow_constructible<second_type, _U2>::value))
: first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
template<class _U1, class _U2, _EnableB<
@@ -436,6 +446,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair(_U1&& __u1, _U2&& __u2)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
+ is_nothrow_constructible<second_type, _U2>::value))
: first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
template<class _U1, class _U2, _EnableB<
@@ -443,6 +455,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit pair(pair<_U1, _U2> const& __p)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
+ is_nothrow_constructible<second_type, _U2 const&>::value))
: first(__p.first), second(__p.second) {}
template<class _U1, class _U2, _EnableB<
@@ -450,6 +464,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair(pair<_U1, _U2> const& __p)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
+ is_nothrow_constructible<second_type, _U2 const&>::value))
: first(__p.first), second(__p.second) {}
template<class _U1, class _U2, _EnableB<
@@ -457,6 +473,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit pair(pair<_U1, _U2>&&__p)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
+ is_nothrow_constructible<second_type, _U2&&>::value))
: first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
template<class _U1, class _U2, _EnableB<
@@ -464,6 +482,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
> = false>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
pair(pair<_U1, _U2>&& __p)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
+ is_nothrow_constructible<second_type, _U2&&>::value))
: first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
template<class _Tuple, _EnableB<
@@ -486,6 +506,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
_LIBCPP_INLINE_VISIBILITY
pair(piecewise_construct_t __pc,
tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
+ is_nothrow_constructible<second_type, _Args2...>::value))
: pair(__pc, __first_args, __second_args,
typename __make_tuple_indices<sizeof...(_Args1)>::type(),
typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
@@ -615,32 +637,37 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
__x.swap(__y);
}
-#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp>
+struct __unwrap_reference { typedef _Tp type; };
template <class _Tp>
-struct __make_pair_return_impl
-{
- typedef _Tp type;
-};
+struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _Tp& type; };
+#if _LIBCPP_STD_VER > 17
template <class _Tp>
-struct __make_pair_return_impl<reference_wrapper<_Tp>>
-{
- typedef _Tp& type;
-};
+struct unwrap_reference : __unwrap_reference<_Tp> { };
template <class _Tp>
-struct __make_pair_return
-{
- typedef typename __make_pair_return_impl<typename decay<_Tp>::type>::type type;
-};
+struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { };
+#endif // > C++17
+
+template <class _Tp>
+struct __unwrap_ref_decay
+#if _LIBCPP_STD_VER > 17
+ : unwrap_ref_decay<_Tp>
+#else
+ : __unwrap_reference<typename decay<_Tp>::type>
+#endif
+{ };
+
+#ifndef _LIBCPP_CXX03_LANG
template <class _T1, class _T2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
+pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
make_pair(_T1&& __t1, _T2&& __t2)
{
- return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
+ return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
}
@@ -657,7 +684,7 @@ make_pair(_T1 __x, _T2 __y)
#endif // _LIBCPP_CXX03_LANG
template <class _T1, class _T2>
- class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
+ struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
: public integral_constant<size_t, 2> {};
template <size_t _Ip, class _T1, class _T2>
@@ -988,8 +1015,10 @@ __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
{
case 3:
__h ^= __data[2] << 16;
+ _LIBCPP_FALLTHROUGH();
case 2:
__h ^= __data[1] << 8;
+ _LIBCPP_FALLTHROUGH();
case 1:
__h ^= __data[0];
__h *= __m;
@@ -1453,7 +1482,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<float>
size_t operator()(float __v) const _NOEXCEPT
{
// -0.0 and 0.0 should return same hash
- if (__v == 0)
+ if (__v == 0.0)
return 0;
return __scalar_hash<float>::operator()(__v);
}
@@ -1467,7 +1496,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<double>
size_t operator()(double __v) const _NOEXCEPT
{
// -0.0 and 0.0 should return same hash
- if (__v == 0)
+ if (__v == 0.0)
return 0;
return __scalar_hash<double>::operator()(__v);
}
@@ -1481,7 +1510,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<long double>
size_t operator()(long double __v) const _NOEXCEPT
{
// -0.0 and 0.0 should return same hash
- if (__v == 0)
+ if (__v == 0.0)
return 0;
#if defined(__i386__)
// Zero out padding bits
diff --git a/include/valarray b/include/valarray
index 8d3892ad35d9..07f38c811509 100644
--- a/include/valarray
+++ b/include/valarray
@@ -803,7 +803,7 @@ public:
// construct/destroy:
_LIBCPP_INLINE_VISIBILITY
valarray() : __begin_(0), __end_(0) {}
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit valarray(size_t __n);
_LIBCPP_INLINE_VISIBILITY
valarray(const value_type& __x, size_t __n);
@@ -818,7 +818,7 @@ public:
valarray(const gslice_array<value_type>& __ga);
valarray(const mask_array<value_type>& __ma);
valarray(const indirect_array<value_type>& __ia);
- inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
+ inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
~valarray();
// assignment:
@@ -1054,7 +1054,8 @@ private:
const _Up*
end(const valarray<_Up>& __v);
- void __clear();
+ _LIBCPP_INLINE_VISIBILITY
+ void __clear(size_t __capacity);
valarray& __assign_range(const value_type* __f, const value_type* __l);
};
@@ -2739,7 +2740,7 @@ __val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const
__r.__begin_ =
__r.__end_ =
static_cast<result_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(result_type), _LIBCPP_ALIGNOF(result_type)));
for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
::new (__r.__end_) result_type(__expr_[__i]);
}
@@ -2757,18 +2758,18 @@ valarray<_Tp>::valarray(size_t __n)
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (; __n; --__n, ++__end_)
+ for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
::new (__end_) value_type();
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2792,18 +2793,18 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (; __n; ++__end_, ++__p, --__n)
+ for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left)
::new (__end_) value_type(*__p);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2818,7 +2819,7 @@ valarray<_Tp>::valarray(const valarray& __v)
if (__v.size())
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2829,7 +2830,7 @@ valarray<_Tp>::valarray(const valarray& __v)
}
catch (...)
{
- __clear();
+ __clear(__v.size());
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2852,22 +2853,23 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
: __begin_(0),
__end_(0)
{
- size_t __n = __il.size();
+ const size_t __n = __il.size();
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
-_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+_VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n)
+ size_t __n_left = __n;
+ for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left)
::new (__end_) value_type(*__p);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2881,22 +2883,23 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
: __begin_(0),
__end_(0)
{
- size_t __n = __sa.__size_;
+ const size_t __n = __sa.__size_;
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n)
+ size_t __n_left = __n;
+ for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left)
::new (__end_) value_type(*__p);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2908,11 +2911,11 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
: __begin_(0),
__end_(0)
{
- size_t __n = __ga.__1d_.size();
+ const size_t __n = __ga.__1d_.size();
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2926,7 +2929,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2938,11 +2941,11 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
: __begin_(0),
__end_(0)
{
- size_t __n = __ma.__1d_.size();
+ const size_t __n = __ma.__1d_.size();
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2956,7 +2959,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2968,11 +2971,11 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
: __begin_(0),
__end_(0)
{
- size_t __n = __ia.__1d_.size();
+ const size_t __n = __ia.__1d_.size();
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2986,7 +2989,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -2997,7 +3000,7 @@ template <class _Tp>
inline
valarray<_Tp>::~valarray()
{
- __clear();
+ __clear(size());
}
template <class _Tp>
@@ -3007,9 +3010,9 @@ valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l)
size_t __n = __l - __f;
if (size() != __n)
{
- __clear();
+ __clear(size());
__begin_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
__end_ = __begin_ + __n;
_VSTD::uninitialized_copy(__f, __l, __begin_);
} else {
@@ -3034,7 +3037,7 @@ inline
valarray<_Tp>&
valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT
{
- __clear();
+ __clear(size());
__begin_ = __v.__begin_;
__end_ = __v.__end_;
__v.__begin_ = nullptr;
@@ -3265,7 +3268,7 @@ valarray<_Tp>::operator+() const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(+*__p);
}
@@ -3283,7 +3286,7 @@ valarray<_Tp>::operator-() const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(-*__p);
}
@@ -3301,7 +3304,7 @@ valarray<_Tp>::operator~() const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(~*__p);
}
@@ -3318,7 +3321,7 @@ valarray<_Tp>::operator!() const
{
__r.__begin_ =
__r.__end_ =
- static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), __alignof(bool)));
+ static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), _LIBCPP_ALIGNOF(bool)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) bool(!*__p);
}
@@ -3639,7 +3642,7 @@ valarray<_Tp>::shift(int __i) const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
const value_type* __sb;
value_type* __tb;
value_type* __te;
@@ -3678,7 +3681,7 @@ valarray<_Tp>::cshift(int __i) const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
__i %= static_cast<int>(__n);
const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;
for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)
@@ -3700,7 +3703,7 @@ valarray<_Tp>::apply(value_type __f(value_type)) const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(__f(*__p));
}
@@ -3718,7 +3721,7 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(__f(*__p));
}
@@ -3726,38 +3729,38 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const
}
template <class _Tp>
-void
-valarray<_Tp>::__clear()
+inline
+void valarray<_Tp>::__clear(size_t __capacity)
{
- if (__begin_ != nullptr)
- {
- while (__end_ != __begin_)
- (--__end_)->~value_type();
- _VSTD::__libcpp_deallocate(__begin_, __alignof(value_type));
- __begin_ = __end_ = nullptr;
- }
+ if (__begin_ != nullptr)
+ {
+ while (__end_ != __begin_)
+ (--__end_)->~value_type();
+ _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), _LIBCPP_ALIGNOF(value_type));
+ __begin_ = __end_ = nullptr;
+ }
}
template <class _Tp>
void
valarray<_Tp>::resize(size_t __n, value_type __x)
{
- __clear();
+ __clear(size());
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (; __n; --__n, ++__end_)
+ for (size_t __n_left = __n; __n_left; --__n_left, ++__end_)
::new (__end_) value_type(__x);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __clear();
+ __clear(__n);
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
diff --git a/include/variant b/include/variant
index f9098f42249a..a4339de6cde4 100644
--- a/include/variant
+++ b/include/variant
@@ -23,8 +23,8 @@ namespace std {
// 20.7.2.1, constructors
constexpr variant() noexcept(see below);
- variant(const variant&);
- variant(variant&&) noexcept(see below);
+ variant(const variant&); // constexpr in C++20
+ variant(variant&&) noexcept(see below); // constexpr in C++20
template <class T> constexpr variant(T&&) noexcept(see below);
@@ -46,8 +46,8 @@ namespace std {
~variant();
// 20.7.2.3, assignment
- variant& operator=(const variant&);
- variant& operator=(variant&&) noexcept(see below);
+ variant& operator=(const variant&); // constexpr in C++20
+ variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
template <class T> variant& operator=(T&&) noexcept(see below);
@@ -208,6 +208,7 @@ namespace std {
#include <type_traits>
#include <utility>
#include <limits>
+#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -218,7 +219,7 @@ _LIBCPP_PUSH_MACROS
namespace std { // explicitly not using versioning namespace
-class _LIBCPP_EXCEPTION_ABI bad_variant_access : public exception {
+class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
public:
virtual const char* what() const _NOEXCEPT;
};
@@ -231,6 +232,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_NORETURN
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
void __throw_bad_variant_access() {
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_variant_access();
@@ -1064,7 +1066,7 @@ public:
#ifndef _LIBCPP_NO_EXCEPTIONS
// EXTENSION: When the move construction of `__lhs` into `__rhs` throws
// and `__tmp` is nothrow move constructible then we move `__tmp` back
- // into `__rhs` and provide the strong exception safety guarentee.
+ // into `__rhs` and provide the strong exception safety guarantee.
try {
this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
} catch (...) {
@@ -1320,7 +1322,8 @@ constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
template <size_t _Ip, class _Vp>
inline _LIBCPP_INLINE_VISIBILITY
-static constexpr auto&& __generic_get(_Vp&& __v) {
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
+constexpr auto&& __generic_get(_Vp&& __v) {
using __variant_detail::__access::__variant;
if (!__holds_alternative<_Ip>(__v)) {
__throw_bad_variant_access();
@@ -1330,6 +1333,7 @@ static constexpr auto&& __generic_get(_Vp&& __v) {
template <size_t _Ip, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
variant<_Types...>& __v) {
static_assert(_Ip < sizeof...(_Types));
@@ -1339,6 +1343,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
template <size_t _Ip, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
variant<_Types...>&& __v) {
static_assert(_Ip < sizeof...(_Types));
@@ -1348,6 +1353,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
template <size_t _Ip, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
const variant<_Types...>& __v) {
static_assert(_Ip < sizeof...(_Types));
@@ -1357,6 +1363,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
template <size_t _Ip, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
const variant<_Types...>&& __v) {
static_assert(_Ip < sizeof...(_Types));
@@ -1366,6 +1373,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
template <class _Tp, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr _Tp& get(variant<_Types...>& __v) {
static_assert(!is_void_v<_Tp>);
return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
@@ -1373,6 +1381,7 @@ constexpr _Tp& get(variant<_Types...>& __v) {
template <class _Tp, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr _Tp&& get(variant<_Types...>&& __v) {
static_assert(!is_void_v<_Tp>);
return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
@@ -1381,6 +1390,7 @@ constexpr _Tp&& get(variant<_Types...>&& __v) {
template <class _Tp, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr const _Tp& get(const variant<_Types...>& __v) {
static_assert(!is_void_v<_Tp>);
return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
@@ -1388,6 +1398,7 @@ constexpr const _Tp& get(const variant<_Types...>& __v) {
template <class _Tp, class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr const _Tp&& get(const variant<_Types...>&& __v) {
static_assert(!is_void_v<_Tp>);
return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
@@ -1437,6 +1448,16 @@ get_if(const variant<_Types...>* __v) noexcept {
return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
}
+template <class _Operator>
+struct __convert_to_bool {
+ template <class _T1, class _T2>
+ _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
+ static_assert(std::is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
+ "the relational operator does not return a type which is implicitly convertible to bool");
+ return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
+ }
+};
+
template <class... _Types>
inline _LIBCPP_INLINE_VISIBILITY
constexpr bool operator==(const variant<_Types...>& __lhs,
@@ -1444,7 +1465,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs,
using __variant_detail::__visitation::__variant;
if (__lhs.index() != __rhs.index()) return false;
if (__lhs.valueless_by_exception()) return true;
- return __variant::__visit_value_at(__lhs.index(), equal_to<>{}, __lhs, __rhs);
+ return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
}
template <class... _Types>
@@ -1455,7 +1476,7 @@ constexpr bool operator!=(const variant<_Types...>& __lhs,
if (__lhs.index() != __rhs.index()) return true;
if (__lhs.valueless_by_exception()) return false;
return __variant::__visit_value_at(
- __lhs.index(), not_equal_to<>{}, __lhs, __rhs);
+ __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
}
template <class... _Types>
@@ -1467,7 +1488,7 @@ constexpr bool operator<(const variant<_Types...>& __lhs,
if (__lhs.valueless_by_exception()) return true;
if (__lhs.index() < __rhs.index()) return true;
if (__lhs.index() > __rhs.index()) return false;
- return __variant::__visit_value_at(__lhs.index(), less<>{}, __lhs, __rhs);
+ return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
}
template <class... _Types>
@@ -1479,7 +1500,7 @@ constexpr bool operator>(const variant<_Types...>& __lhs,
if (__rhs.valueless_by_exception()) return true;
if (__lhs.index() > __rhs.index()) return true;
if (__lhs.index() < __rhs.index()) return false;
- return __variant::__visit_value_at(__lhs.index(), greater<>{}, __lhs, __rhs);
+ return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
}
template <class... _Types>
@@ -1492,7 +1513,7 @@ constexpr bool operator<=(const variant<_Types...>& __lhs,
if (__lhs.index() < __rhs.index()) return true;
if (__lhs.index() > __rhs.index()) return false;
return __variant::__visit_value_at(
- __lhs.index(), less_equal<>{}, __lhs, __rhs);
+ __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
}
template <class... _Types>
@@ -1505,11 +1526,12 @@ constexpr bool operator>=(const variant<_Types...>& __lhs,
if (__lhs.index() > __rhs.index()) return true;
if (__lhs.index() < __rhs.index()) return false;
return __variant::__visit_value_at(
- __lhs.index(), greater_equal<>{}, __lhs, __rhs);
+ __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
}
template <class _Visitor, class... _Vs>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
using __variant_detail::__visitation::__variant;
bool __results[] = {__vs.valueless_by_exception()...};
diff --git a/include/vector b/include/vector
index 0f5006f37567..edb6d3e09f5f 100644
--- a/include/vector
+++ b/include/vector
@@ -261,6 +261,11 @@ template <class T, class Allocator>
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
noexcept(noexcept(x.swap(y)));
+template <class T, class Allocator, class U>
+ void erase(vector<T, Allocator>& c, const U& value); // C++20
+template <class T, class Allocator, class Predicate>
+ void erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
+
} // std
*/
@@ -276,6 +281,7 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
#include <stdexcept>
#include <algorithm>
#include <cstring>
+#include <version>
#include <__split_buffer>
#include <__functional_base>
@@ -540,13 +546,14 @@ public:
value_type,
typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
-#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_INLINE_VISIBILITY
~vector()
{
+ __annotate_delete();
+#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__erase_c(this);
- }
#endif
+ }
vector(const vector& __x);
vector(const vector& __x, const allocator_type& __a);
@@ -2453,7 +2460,7 @@ private:
void __vdeallocate() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static size_type __align_it(size_type __new_size) _NOEXCEPT
- {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);};
+ {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);}
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
_LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);
template <class _ForwardIterator>
@@ -2604,6 +2611,13 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
{
size_type __old_size = this->__size_;
this->__size_ += __n;
+ if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word))
+ {
+ if (this->__size_ <= __bits_per_word)
+ this->__begin_[0] = __storage_type(0);
+ else
+ this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
+ }
_VSTD::fill_n(__make_iter(__old_size), __n, __x);
}
@@ -2618,6 +2632,13 @@ vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardI
{
size_type __old_size = this->__size_;
this->__size_ += _VSTD::distance(__first, __last);
+ if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word))
+ {
+ if (this->__size_ <= __bits_per_word)
+ this->__begin_[0] = __storage_type(0);
+ else
+ this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
+ }
_VSTD::copy(__first, __last, __make_iter(__old_size));
}
@@ -3392,6 +3413,18 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
__x.swap(__y);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Tp, class _Allocator, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase(vector<_Tp, _Allocator>& __c, const _Up& __v)
+{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
+
+template <class _Tp, class _Allocator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred)
+{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
+#endif
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/include/version b/include/version
index 23a872ea85ac..e37afc448601 100644
--- a/include/version
+++ b/include/version
@@ -12,7 +12,105 @@
#define _LIBCPP_VERSIONH
/*
- version synopsis
+ version synopsis
+
+Macro name Value Headers
+__cpp_lib_addressof_constexpr 201603L <memory>
+__cpp_lib_allocator_traits_is_always_equal 201411L <memory> <scoped_allocator> <string>
+ <deque> <forward_list> <list>
+ <vector> <map> <set>
+ <unordered_map> <unordered_set>
+__cpp_lib_any 201606L <any>
+__cpp_lib_apply 201603L <tuple>
+__cpp_lib_array_constexpr 201603L <iterator> <array>
+__cpp_lib_as_const 201510L <utility>
+__cpp_lib_atomic_is_always_lock_free 201603L <atomic>
+__cpp_lib_atomic_ref 201806L <atomic>
+__cpp_lib_bind_front 201811L <functional>
+__cpp_lib_bit_cast 201806L <bit>
+__cpp_lib_bool_constant 201505L <type_traits>
+__cpp_lib_boyer_moore_searcher 201603L <functional>
+__cpp_lib_byte 201603L <cstddef>
+__cpp_lib_char8_t 201811L <atomic> <filesystem> <istream>
+ <limits> <locale> <ostream>
+ <string> <string_view>
+__cpp_lib_chrono 201611L <chrono>
+__cpp_lib_chrono_udls 201304L <chrono>
+__cpp_lib_clamp 201603L <algorithm>
+__cpp_lib_complex_udls 201309L <complex>
+__cpp_lib_concepts 201806L <concepts>
+__cpp_lib_constexpr_misc 201811L <array> <functional> <iterator>
+ <string_view> <tuple> <utility>
+__cpp_lib_constexpr_swap_algorithms 201806L <algorithm>
+__cpp_lib_destroying_delete 201806L <new>
+__cpp_lib_enable_shared_from_this 201603L <memory>
+__cpp_lib_erase_if 201811L <string> <deque> <forward_list>
+ <list> <vector> <map>
+ <set> <unordered_map> <unordered_set>
+__cpp_lib_exchange_function 201304L <utility>
+__cpp_lib_execution 201603L <execution>
+__cpp_lib_filesystem 201703L <filesystem>
+__cpp_lib_gcd_lcm 201606L <numeric>
+__cpp_lib_generic_associative_lookup 201304L <map> <set>
+__cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set>
+__cpp_lib_hardware_interference_size 201703L <new>
+__cpp_lib_has_unique_object_representations 201606L <type_traits>
+__cpp_lib_hypot 201603L <cmath>
+__cpp_lib_incomplete_container_elements 201505L <forward_list> <list> <vector>
+__cpp_lib_integer_sequence 201304L <utility>
+__cpp_lib_integral_constant_callable 201304L <type_traits>
+__cpp_lib_invoke 201411L <functional>
+__cpp_lib_is_aggregate 201703L <type_traits>
+__cpp_lib_is_constant_evaluated 201811L <type_traits>
+__cpp_lib_is_final 201402L <type_traits>
+__cpp_lib_is_invocable 201703L <type_traits>
+__cpp_lib_is_null_pointer 201309L <type_traits>
+__cpp_lib_is_swappable 201603L <type_traits>
+__cpp_lib_launder 201606L <new>
+__cpp_lib_list_remove_return_type 201806L <forward_list> <list>
+__cpp_lib_logical_traits 201510L <type_traits>
+__cpp_lib_make_from_tuple 201606L <tuple>
+__cpp_lib_make_reverse_iterator 201402L <iterator>
+__cpp_lib_make_unique 201304L <memory>
+__cpp_lib_map_try_emplace 201411L <map>
+__cpp_lib_math_special_functions 201603L <cmath>
+__cpp_lib_memory_resource 201603L <memory_resource>
+__cpp_lib_node_extract 201606L <map> <set> <unordered_map>
+ <unordered_set>
+__cpp_lib_nonmember_container_access 201411L <iterator> <array> <deque>
+ <forward_list> <list> <map>
+ <regex> <set> <string>
+ <unordered_map> <unordered_set> <vector>
+__cpp_lib_not_fn 201603L <functional>
+__cpp_lib_null_iterators 201304L <iterator>
+__cpp_lib_optional 201606L <optional>
+__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric>
+__cpp_lib_quoted_string_io 201304L <iomanip>
+__cpp_lib_ranges 201811L <algorithm> <functional> <iterator>
+ <memory> <ranges>
+__cpp_lib_raw_memory_algorithms 201606L <memory>
+__cpp_lib_result_of_sfinae 201210L <functional> <type_traits>
+__cpp_lib_robust_nonmodifying_seq_ops 201304L <algorithm>
+__cpp_lib_sample 201603L <algorithm>
+__cpp_lib_scoped_lock 201703L <mutex>
+__cpp_lib_shared_mutex 201505L <shared_mutex>
+__cpp_lib_shared_ptr_arrays 201611L <memory>
+__cpp_lib_shared_ptr_weak_type 201606L <memory>
+__cpp_lib_shared_timed_mutex 201402L <shared_mutex>
+__cpp_lib_string_udls 201304L <string>
+__cpp_lib_string_view 201606L <string> <string_view>
+__cpp_lib_three_way_comparison 201711L <compare>
+__cpp_lib_to_chars 201611L <utility>
+__cpp_lib_transformation_trait_aliases 201304L <type_traits>
+__cpp_lib_transparent_operators 201510L <functional>
+ 201210L // C++14
+__cpp_lib_tuple_element_t 201402L <tuple>
+__cpp_lib_tuples_by_type 201304L <utility> <tuple>
+__cpp_lib_type_trait_variable_templates 201510L <type_traits>
+__cpp_lib_uncaught_exceptions 201411L <exception>
+__cpp_lib_unordered_map_try_emplace 201411L <unordered_map>
+__cpp_lib_variant 201606L <variant>
+__cpp_lib_void_t 201411L <type_traits>
*/
@@ -22,4 +120,113 @@
#pragma GCC system_header
#endif
-#endif // _LIBCPP_VERSIONH
+#if _LIBCPP_STD_VER > 11
+# define __cpp_lib_chrono_udls 201304L
+# define __cpp_lib_complex_udls 201309L
+# define __cpp_lib_exchange_function 201304L
+# define __cpp_lib_generic_associative_lookup 201304L
+# define __cpp_lib_integer_sequence 201304L
+# define __cpp_lib_integral_constant_callable 201304L
+# define __cpp_lib_is_final 201402L
+# define __cpp_lib_is_null_pointer 201309L
+# define __cpp_lib_make_reverse_iterator 201402L
+# define __cpp_lib_make_unique 201304L
+# define __cpp_lib_null_iterators 201304L
+# define __cpp_lib_quoted_string_io 201304L
+# define __cpp_lib_result_of_sfinae 201210L
+# define __cpp_lib_robust_nonmodifying_seq_ops 201304L
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# define __cpp_lib_shared_timed_mutex 201402L
+# endif
+# define __cpp_lib_string_udls 201304L
+# define __cpp_lib_transformation_trait_aliases 201304L
+# define __cpp_lib_transparent_operators 201210L
+# define __cpp_lib_tuple_element_t 201402L
+# define __cpp_lib_tuples_by_type 201304L
+#endif
+
+#if _LIBCPP_STD_VER > 14
+# if !defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)
+# define __cpp_lib_addressof_constexpr 201603L
+# endif
+# define __cpp_lib_allocator_traits_is_always_equal 201411L
+# define __cpp_lib_any 201606L
+# define __cpp_lib_apply 201603L
+# define __cpp_lib_array_constexpr 201603L
+# define __cpp_lib_as_const 201510L
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# define __cpp_lib_atomic_is_always_lock_free 201603L
+# endif
+# define __cpp_lib_bool_constant 201505L
+// # define __cpp_lib_boyer_moore_searcher 201603L
+# define __cpp_lib_byte 201603L
+# define __cpp_lib_chrono 201611L
+# define __cpp_lib_clamp 201603L
+# define __cpp_lib_enable_shared_from_this 201603L
+// # define __cpp_lib_execution 201603L
+# define __cpp_lib_filesystem 201703L
+# define __cpp_lib_gcd_lcm 201606L
+# define __cpp_lib_hardware_interference_size 201703L
+# if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
+# define __cpp_lib_has_unique_object_representations 201606L
+# endif
+# define __cpp_lib_hypot 201603L
+# define __cpp_lib_incomplete_container_elements 201505L
+# define __cpp_lib_invoke 201411L
+# if !defined(_LIBCPP_HAS_NO_IS_AGGREGATE)
+# define __cpp_lib_is_aggregate 201703L
+# endif
+# define __cpp_lib_is_invocable 201703L
+# define __cpp_lib_is_swappable 201603L
+# define __cpp_lib_launder 201606L
+# define __cpp_lib_logical_traits 201510L
+# define __cpp_lib_make_from_tuple 201606L
+# define __cpp_lib_map_try_emplace 201411L
+// # define __cpp_lib_math_special_functions 201603L
+// # define __cpp_lib_memory_resource 201603L
+# define __cpp_lib_node_extract 201606L
+# define __cpp_lib_nonmember_container_access 201411L
+# define __cpp_lib_not_fn 201603L
+# define __cpp_lib_optional 201606L
+// # define __cpp_lib_parallel_algorithm 201603L
+# define __cpp_lib_raw_memory_algorithms 201606L
+# define __cpp_lib_sample 201603L
+# define __cpp_lib_scoped_lock 201703L
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# define __cpp_lib_shared_mutex 201505L
+# endif
+// # define __cpp_lib_shared_ptr_arrays 201611L
+# define __cpp_lib_shared_ptr_weak_type 201606L
+# define __cpp_lib_string_view 201606L
+// # define __cpp_lib_to_chars 201611L
+# undef __cpp_lib_transparent_operators
+# define __cpp_lib_transparent_operators 201510L
+# define __cpp_lib_type_trait_variable_templates 201510L
+# define __cpp_lib_uncaught_exceptions 201411L
+# define __cpp_lib_unordered_map_try_emplace 201411L
+# define __cpp_lib_variant 201606L
+# define __cpp_lib_void_t 201411L
+#endif
+
+#if _LIBCPP_STD_VER > 17
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+// # define __cpp_lib_atomic_ref 201806L
+# endif
+// # define __cpp_lib_bind_front 201811L
+// # define __cpp_lib_bit_cast 201806L
+# if !defined(_LIBCPP_NO_HAS_CHAR8_T)
+# define __cpp_lib_char8_t 201811L
+# endif
+// # define __cpp_lib_concepts 201806L
+// # define __cpp_lib_constexpr_misc 201811L
+// # define __cpp_lib_constexpr_swap_algorithms 201806L
+// # define __cpp_lib_destroying_delete 201806L
+# define __cpp_lib_erase_if 201811L
+// # define __cpp_lib_generic_unordered_lookup 201811L
+// # define __cpp_lib_is_constant_evaluated 201811L
+// # define __cpp_lib_list_remove_return_type 201806L
+// # define __cpp_lib_ranges 201811L
+// # define __cpp_lib_three_way_comparison 201711L
+#endif
+
+#endif // _LIBCPP_VERSIONH
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index e068edc8a7af..24489e8fb5e8 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -41,14 +41,14 @@ add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}")
if (APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR
LIBCXX_CXX_ABI_LIBNAME STREQUAL "default"))
- set(LIBCXX_OSX_REEXPORT_SYSTEM_ABI_LIBRARY ON)
+ set(LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS ON)
endif()
if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
add_library_flags("-Wl,--whole-archive" "-Wl,-Bstatic")
add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}")
add_library_flags("-Wl,-Bdynamic" "-Wl,--no-whole-archive")
-elseif (LIBCXX_OSX_REEXPORT_SYSTEM_ABI_LIBRARY)
+elseif (LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS)
add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}")
else ()
add_interface_library("${LIBCXX_CXX_ABI_LIBRARY}")
@@ -129,7 +129,7 @@ if (LIBCXX_TARGETING_MSVC)
add_library_flags(iso_stdio_wide_specifiers)
endif()
-if (LIBCXX_OSX_REEXPORT_SYSTEM_ABI_LIBRARY)
+if (LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS)
if (NOT DEFINED LIBCXX_LIBCPPABI_VERSION)
set(LIBCXX_LIBCPPABI_VERSION "2") # Default value
execute_process(
@@ -149,80 +149,95 @@ if (LIBCXX_OSX_REEXPORT_SYSTEM_ABI_LIBRARY)
endif()
if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" )
- add_definitions(-D__STRICT_ANSI__)
- add_link_flags(
- "-compatibility_version 1"
- "-current_version 1"
- "-install_name /usr/lib/libc++.1.dylib"
- "-Wl,-reexport_library,/usr/lib/libc++abi.dylib"
- "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
- "/usr/lib/libSystem.B.dylib")
+ message(FATAL_ERROR "Mac OSX 10.6 is not supported anymore as a deployment "
+ "target. If you need support for this, please contact "
+ "the libc++ maintainers.")
else()
- if (DEFINED CMAKE_OSX_SYSROOT AND NOT CMAKE_OSX_SYSROOT STREQUAL "")
- list(FIND CMAKE_OSX_ARCHITECTURES "armv7" OSX_HAS_ARMV7)
- if (NOT OSX_HAS_ARMV7 EQUAL -1)
- set(OSX_RE_EXPORT_LINE
- "${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib"
- "-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp")
- else()
- set(OSX_RE_EXPORT_LINE
- "-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib")
- endif()
+ if ("armv7" IN_LIST CMAKE_OSX_ARCHITECTURES)
+ set(RE_EXPORT_LIST "${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp")
else()
- set(OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
- if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
- add_link_flags("/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi-new-delete.exp")
- endif()
+ set(RE_EXPORT_LIST "${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
endif()
add_link_flags(
"-compatibility_version 1"
"-install_name /usr/lib/libc++.1.dylib"
- "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
- "${OSX_RE_EXPORT_LINE}"
- "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp"
- "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp")
+ "-Wl,-unexported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp\""
+ "-Wl,-reexported_symbols_list,\"${RE_EXPORT_LIST}\""
+ "-Wl,-force_symbols_not_weak_list,\"${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp\""
+ "-Wl,-force_symbols_weak_list,\"${CMAKE_CURRENT_SOURCE_DIR}/weak.exp\"")
+
+ if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
+ add_link_flags("-Wl,-reexported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/libc++abi-new-delete.exp\"")
+ endif()
endif()
endif()
split_list(LIBCXX_COMPILE_FLAGS)
split_list(LIBCXX_LINK_FLAGS)
-# Add an object library that contains the compiled source files.
-add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
-if(LIBCXX_CXX_ABI_HEADER_TARGET)
- add_dependencies(cxx_objects ${LIBCXX_CXX_ABI_HEADER_TARGET})
-endif()
-if(WIN32 AND NOT MINGW)
- target_compile_definitions(cxx_objects
- 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()
+macro(cxx_object_library name)
+ cmake_parse_arguments(ARGS "" "" "DEFINES;FLAGS" ${ARGN})
-set_target_properties(cxx_objects
- PROPERTIES
- COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
-)
+ # Add an object library that contains the compiled source files.
+ add_library(${name} OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
+ if(LIBCXX_CXX_ABI_HEADER_TARGET)
+ add_dependencies(${name} ${LIBCXX_CXX_ABI_HEADER_TARGET})
+ endif()
+ if(WIN32 AND NOT MINGW)
+ target_compile_definitions(${name}
+ 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()
+
+ if(ARGS_DEFINES)
+ target_compile_definitions(${name} PRIVATE ${ARGS_DEFINES})
+ endif()
+
+ set_target_properties(${name}
+ PROPERTIES
+ COMPILE_FLAGS ${LIBCXX_COMPILE_FLAGS}
+ )
+
+ if(ARGS_FLAGS)
+ target_compile_options(${name} PRIVATE ${ARGS_FLAGS})
+ endif()
+endmacro()
+
+if(LIBCXX_HERMETIC_STATIC_LIBRARY)
+ append_flags_if_supported(CXX_STATIC_OBJECTS_FLAGS -fvisibility=hidden)
+ append_flags_if_supported(CXX_STATIC_OBJECTS_FLAGS -fvisibility-global-new-delete-hidden)
+ cxx_object_library(cxx_static_objects
+ DEFINES _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
+ FLAGS ${CXX_STATIC_OBJECTS_FLAGS})
+ cxx_object_library(cxx_shared_objects)
+ set(cxx_static_sources $<TARGET_OBJECTS:cxx_static_objects>)
+ set(cxx_shared_sources $<TARGET_OBJECTS:cxx_shared_objects>)
+else()
+ cxx_object_library(cxx_objects)
+ set(cxx_static_sources $<TARGET_OBJECTS:cxx_objects>)
+ set(cxx_shared_sources $<TARGET_OBJECTS:cxx_objects>)
+endif()
# Build the shared library.
if (LIBCXX_ENABLE_SHARED)
- add_library(cxx_shared SHARED $<TARGET_OBJECTS:cxx_objects>)
+ add_library(cxx_shared SHARED ${cxx_shared_sources})
if(COMMAND llvm_setup_rpath)
llvm_setup_rpath(cxx_shared)
endif()
@@ -249,7 +264,7 @@ endif()
# Build the static library.
if (LIBCXX_ENABLE_STATIC)
- add_library(cxx_static STATIC $<TARGET_OBJECTS:cxx_objects>)
+ add_library(cxx_static STATIC ${cxx_static_sources})
target_link_libraries(cxx_static ${LIBCXX_LIBRARIES})
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
set_target_properties(cxx_static
diff --git a/lib/abi/CHANGELOG.TXT b/lib/abi/CHANGELOG.TXT
index c1237338fbb8..38dffd2908b7 100644
--- a/lib/abi/CHANGELOG.TXT
+++ b/lib/abi/CHANGELOG.TXT
@@ -13,9 +13,121 @@ Afterwards the ABI list should be updated to include the new changes.
New entries should be added directly below the "Version" header.
-----------
+Version 8.0
+-----------
+
+* rXXXXX - Remove std::bad_array_length
+
+ The change removes the definition of std::bad_array_length (which never made
+ it into the standard) from the headers and the dylib. This is technically an
+ ABI break because the symbols are shipped starting with mac OSX 10.13, however
+ users couldn't be relying on the functionality because it is marked as being
+ unavailable using Clang's availability attribute.
+
+ x86_64-apple-darwin16.0
+ -----------------------
+ Symbol removed: __ZNKSt16bad_array_length4whatEv
+ Symbol removed: __ZNKSt16bad_array_length4whatEv
+ Symbol removed: __ZNSt16bad_array_lengthC1Ev
+ Symbol removed: __ZNSt16bad_array_lengthC1Ev
+ Symbol removed: __ZNSt16bad_array_lengthC2Ev
+ Symbol removed: __ZNSt16bad_array_lengthC2Ev
+ Symbol removed: __ZNSt16bad_array_lengthD0Ev
+ Symbol removed: __ZNSt16bad_array_lengthD0Ev
+ Symbol removed: __ZNSt16bad_array_lengthD1Ev
+ Symbol removed: __ZNSt16bad_array_lengthD1Ev
+ Symbol removed: __ZNSt16bad_array_lengthD2Ev
+ Symbol removed: __ZNSt16bad_array_lengthD2Ev
+ Symbol removed: __ZTISt16bad_array_length
+ Symbol removed: __ZTISt16bad_array_length
+ Symbol removed: __ZTSSt16bad_array_length
+ Symbol removed: __ZTSSt16bad_array_length
+ Symbol removed: __ZTVSt16bad_array_length
+ Symbol removed: __ZTVSt16bad_array_length
+
+* r347395 - Making libc++ build under -fvisibility=hidden on Linux
+
+ The change marks several function templates as hidden. This removes symbols
+ from the shared library, but this is not an ABI break because it's impossible
+ for programs linking against libc++.so to actually depend on that symbol.
+ The reason is that the symbol is exported from the shared library through
+ an implicit instantiation present in the shared object itself only. Furthermore,
+ if a user's shared object was implicitly instantiating one of these functions,
+ marking that symbol as hidden would not be an ABI break for them because none
+ of their users could actually be using the symbol in their dylib (because
+ it's an implicit instantiation).
+
+ x86_64-linux-gnu
+ ----------------
+ Symbol removed: _ZNSt3__125__num_get_signed_integralIlEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__125__num_get_signed_integralIxEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__127__num_get_unsigned_integralIjEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__127__num_get_unsigned_integralImEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__127__num_get_unsigned_integralItEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__127__num_get_unsigned_integralIyEET_PKcS3_Rji
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIaaEEPaEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIccEEPcEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIddEEPdEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIffEEPfEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIhhEEPhEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIiiEEPiEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIjjEEPjEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIllEEPlEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessImmEEPmEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIssEEPsEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIttEEPtEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIwwEEPwEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIxxEEPxEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__17__sort5IRNS_6__lessIyyEEPyEEjT0_S5_S5_S5_S5_T_
+ Symbol removed: _ZNSt3__1plIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_12basic_stringIT_T0_T1_EERKS9_PKS6_
+ Symbol removed: _ZSt18make_exception_ptrINSt3__112future_errorEESt13exception_ptrT_
+
+* r345260 - Making libc++ build under -fvisibility=hidden on Mac OS
+
+ The change marks __thread_specific_ptr<__thread_struct>::__at_thread_exit(void*)
+ with hidden visibility. This removes a symbol from the shared libraries,
+ however this is not an ABI break because it's impossible for programs linking
+ against libc++.dylib to actually depend on that symbol. The reason is that
+ the symbol is exported from the shared library through an implicit
+ instantiation present in the dylib itself only. Furthermore, if a user's
+ dylib was implicitly instantiating __thread_specific_ptr<T>::__at_thread_exit
+ (because it's defined in the headers), marking that symbol as hidden would
+ not be an ABI break for them because none of their users could actually be
+ using the symbol in their dylib (because it's an implicit instantiation).
+
+ This change also marks __start_std_streams as hidden -- this variable is
+ only required to initialize the streams, and nobody should depend on it
+ from outside the dylib.
+
+ x86_64-linux-gnu
+ ----------------
+ Symbol removed: _ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
+ Symbol removed: _ZNSt3__119__start_std_streamsE
+
+ x86_64-apple-darwin16.0
+ -----------------------
+ Symbol removed: __ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv
+ Symbol removed: __ZNSt3__119__start_std_streamsE
+
+-----------
Version 7.0
-----------
+* r338479 - Elementary string conversions for integral types
+
+ The change emits __u64toa and __u32toa under std::__1::__itoa.
+
+ x86_64-linux-gnu
+ ----------------
+ Symbol added: _ZNSt3__16__itoa8__u64toaEmPc
+ Symbol added: _ZNSt3__16__itoa8__u32toaEjPc
+
+ x86_64-apple-darwin16.0
+ -----------------------
+ Symbol added: __ZNSt3__16__itoa8__u64toaEyPc
+ Symbol added: __ZNSt3__16__itoa8__u32toaEjPc
+
+
* r333467 - Fix embarrasing typo in uncaught_exceptions.
This bug caused __uncaught_exception to be ODR used instead of
diff --git a/lib/abi/CMakeLists.txt b/lib/abi/CMakeLists.txt
index e42e96173f53..bb9217f88472 100644
--- a/lib/abi/CMakeLists.txt
+++ b/lib/abi/CMakeLists.txt
@@ -1,9 +1,16 @@
if (DEFINED TARGET_TRIPLE)
- # Ignore the major, minor, and patchlevel versions of the darwin
- # target.
- string(REGEX REPLACE "darwin([0-9]+)\\.([0-9]+)\\.([0-9]+)" "darwin"
- GENERIC_TARGET_TRIPLE "${TARGET_TRIPLE}")
+ if (TARGET_TRIPLE MATCHES "darwin")
+ # Ignore the major, minor, and patchlevel versions of darwin targets.
+ string(REGEX REPLACE "darwin[0-9]+\\.[0-9]+\\.[0-9]+" "darwin"
+ GENERIC_TARGET_TRIPLE "${TARGET_TRIPLE}")
+ elseif(TARGET_TRIPLE MATCHES "freebsd")
+ # Ignore the major and minor versions of freebsd targets.
+ string(REGEX REPLACE "freebsd[0-9]+\\.[0-9]+" "freebsd"
+ GENERIC_TARGET_TRIPLE "${TARGET_TRIPLE}")
+ else()
+ set(GENERIC_TARGET_TRIPLE "${TARGET_TRIPLE}")
+ endif()
endif()
# Detect if we are building in the same configuration used to generate
diff --git a/lib/abi/x86_64-apple-darwin.v1.abilist b/lib/abi/x86_64-apple-darwin.v1.abilist
index 1be950f2e540..65a034961341 100644
--- a/lib/abi/x86_64-apple-darwin.v1.abilist
+++ b/lib/abi/x86_64-apple-darwin.v1.abilist
@@ -8,8 +8,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZNKSt13bad_exception4whatEv'}
{'type': 'U', 'is_defined': False, 'name': '__ZNKSt13runtime_error4whatEv'}
{'type': 'I', 'is_defined': True, 'name': '__ZNKSt13runtime_error4whatEv'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNKSt16bad_array_length4whatEv'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNKSt16bad_array_length4whatEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt16nested_exception14rethrow_nestedEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt18bad_variant_access4whatEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt19bad_optional_access4whatEv'}
@@ -527,16 +525,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZNSt15underflow_errorD1Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt15underflow_errorD2Ev'}
{'type': 'I', 'is_defined': True, 'name': '__ZNSt15underflow_errorD2Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthC1Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthC1Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthC2Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthC2Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD0Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD0Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD1Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD1Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD2Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD2Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt16invalid_argumentD0Ev'}
{'type': 'I', 'is_defined': True, 'name': '__ZNSt16invalid_argumentD0Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt16invalid_argumentD1Ev'}
@@ -1197,13 +1185,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__shared_weak_countD2Ev'}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119__start_std_streamsE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119__thread_local_dataEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__119declare_no_pointersEPcm'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__119piecewise_constructE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__120__throw_system_errorEiPKc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__throw_runtime_errorEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121__undeclare_reachableEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutex4lockEv'}
@@ -1282,6 +1268,8 @@
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__15wcerrE', 'size': 0}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__15wclogE', 'size': 0}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__15wcoutE', 'size': 0}
+{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__16__itoa8__u32toaEjPc'}
+{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__16__itoa8__u64toaEyPc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__16__sortIRNS_6__lessIccEEPcEEvT0_S5_T_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__16__sortIRNS_6__lessIddEEPdEEvT0_S5_T_'}
@@ -1804,8 +1792,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTISt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTISt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTISt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTISt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTISt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTISt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTISt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTISt16nested_exception', 'size': 0}
@@ -2059,8 +2045,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTSSt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTSSt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTSSt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTSSt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTSSt16nested_exception', 'size': 0}
@@ -2251,8 +2235,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTVSt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTVSt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTVSt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTVSt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTVSt16nested_exception', 'size': 0}
diff --git a/lib/abi/x86_64-apple-darwin.v2.abilist b/lib/abi/x86_64-apple-darwin.v2.abilist
index 05255a657056..5880a3bfd4f6 100644
--- a/lib/abi/x86_64-apple-darwin.v2.abilist
+++ b/lib/abi/x86_64-apple-darwin.v2.abilist
@@ -8,8 +8,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZNKSt13bad_exception4whatEv'}
{'type': 'U', 'is_defined': False, 'name': '__ZNKSt13runtime_error4whatEv'}
{'type': 'I', 'is_defined': True, 'name': '__ZNKSt13runtime_error4whatEv'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNKSt16bad_array_length4whatEv'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNKSt16bad_array_length4whatEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt16nested_exception14rethrow_nestedEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt18bad_variant_access4whatEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt19bad_optional_access4whatEv'}
@@ -180,8 +178,6 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215__codecvt_utf16IwLb1EE5do_inER11__mbstate_tPKcS5_RS5_PwS7_RS7_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215__codecvt_utf16IwLb1EE6do_outER11__mbstate_tPKwS5_RS5_PcS7_RS7_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215__codecvt_utf16IwLb1EE9do_lengthER11__mbstate_tPKcS5_m'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215basic_streambufIcNS_11char_traitsIcEEE6getlocEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215basic_streambufIwNS_11char_traitsIwEEE6getlocEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__215error_condition7messageEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__217bad_function_call4whatEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNKSt3__217moneypunct_bynameIcLb0EE11do_groupingEv'}
@@ -532,16 +528,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZNSt15underflow_errorD1Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt15underflow_errorD2Ev'}
{'type': 'I', 'is_defined': True, 'name': '__ZNSt15underflow_errorD2Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthC1Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthC1Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthC2Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthC2Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD0Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD0Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD1Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD1Ev'}
-{'type': 'U', 'is_defined': False, 'name': '__ZNSt16bad_array_lengthD2Ev'}
-{'type': 'I', 'is_defined': True, 'name': '__ZNSt16bad_array_lengthD2Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt16invalid_argumentD0Ev'}
{'type': 'I', 'is_defined': True, 'name': '__ZNSt16invalid_argumentD0Ev'}
{'type': 'U', 'is_defined': False, 'name': '__ZNSt16invalid_argumentD1Ev'}
@@ -812,15 +798,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__212system_errorD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__212system_errorD2Ev'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__213allocator_argE', 'size': 0}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getEPcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getEPclc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getERNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getERNS_15basic_streambufIcS2_EEc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getERc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE3getEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE4peekEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE4readEPcl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE4syncEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE5seekgENS_4fposI11__mbstate_tEE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE5seekgExNS_8ios_base7seekdirE'}
@@ -829,18 +811,12 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE6ignoreEli'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE6sentryC1ERS3_b'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE6sentryC2ERS3_b'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE7getlineEPcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE7getlineEPclc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE7putbackEc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEE8readsomeEPcl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEED0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEED2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_8ios_baseES5_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsEPFRNS_9basic_iosIcS2_EES6_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsEPFRS3_S4_E'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsEPNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsERPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsERb'}
@@ -855,15 +831,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsERt'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsERx'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIcNS_11char_traitsIcEEErsERy'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getEPwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getEPwlw'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getERNS_15basic_streambufIwS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getERNS_15basic_streambufIwS2_EEw'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getERw'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE3getEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE4peekEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE4readEPwl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE4syncEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE5seekgENS_4fposI11__mbstate_tEE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE5seekgExNS_8ios_base7seekdirE'}
@@ -872,18 +844,12 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE6ignoreEli'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE6sentryC1ERS3_b'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE6sentryC2ERS3_b'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE7getlineEPwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE7getlineEPwlw'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE7putbackEw'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEE8readsomeEPwl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEED0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEED2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_8ios_baseES5_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsEPFRNS_9basic_iosIwS2_EES6_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsEPFRS3_S4_E'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsEPNS_15basic_streambufIwS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsERPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsERb'}
@@ -899,24 +865,15 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsERx'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_istreamIwNS_11char_traitsIwEEErsERy'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE3putEc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE5flushEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE5seekpENS_4fposI11__mbstate_tEE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE5seekpExNS_8ios_base7seekdirE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE5tellpEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE5writeEPKcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE6sentryC2ERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEE6sentryD2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEED0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEED2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_8ios_baseES5_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEPFRNS_9basic_iosIcS2_EES6_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEPFRS3_S4_E'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEPKv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEPNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEb'}
@@ -932,24 +889,15 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEx'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIcNS_11char_traitsIcEEElsEy'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE3putEw'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE5flushEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE5seekpENS_4fposI11__mbstate_tEE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE5seekpExNS_8ios_base7seekdirE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE5tellpEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE5writeEPKwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE6sentryC1ERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE6sentryC2ERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE6sentryD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEE6sentryD2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEEC1EPNS_15basic_streambufIwS2_EE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEEC2EPNS_15basic_streambufIwS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEED0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEED2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_8ios_baseES5_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEPFRNS_9basic_iosIwS2_EES6_E'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEPFRS3_S4_E'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEPKv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEPNS_15basic_streambufIwS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__213basic_ostreamIwNS_11char_traitsIwEEElsEb'}
@@ -981,9 +929,6 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214__shared_countD0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214__shared_countD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214__shared_countD2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEE4swapERS3_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEEC1EPNS_15basic_streambufIcS2_EE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEEC2EPNS_15basic_streambufIcS2_EE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEED0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__214basic_iostreamIcNS_11char_traitsIcEEED2Ev'}
@@ -1023,36 +968,18 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215__thread_structC2Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215__thread_structD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215__thread_structD2Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE10pubseekoffExNS_8ios_base7seekdirEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE10pubseekposENS_4fposI11__mbstate_tEEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE4setgEPcS4_S4_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE4setpEPcS4_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE4syncEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5gbumpEi'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5imbueERKNS_6localeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5pbumpEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5sgetcEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5sgetnEPcl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5sputcEc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5sputnEPKcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE5uflowEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE6sbumpcEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE6setbufEPcl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE6snextcEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE6xsgetnEPcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE6xsputnEPKcl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE7pubsyncEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE7seekoffExNS_8ios_base7seekdirEj'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE7seekposENS_4fposI11__mbstate_tEEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE7sungetcEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE8in_availEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE8overflowEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE8pubimbueERKNS_6localeE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE9pbackfailEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE9pubsetbufEPcl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE9showmanycEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE9sputbackcEc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEE9underflowEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEEC1ERKS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEEC1Ev'}
@@ -1062,36 +989,18 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEED1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEED2Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIcNS_11char_traitsIcEEEaSERKS3_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE10pubseekoffExNS_8ios_base7seekdirEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE10pubseekposENS_4fposI11__mbstate_tEEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE4setgEPwS4_S4_'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE4setpEPwS4_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE4swapERS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE4syncEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5gbumpEi'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5imbueERKNS_6localeE'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5pbumpEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5sgetcEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5sgetnEPwl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5sputcEw'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5sputnEPKwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE5uflowEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE6sbumpcEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE6setbufEPwl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE6snextcEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE6xsgetnEPwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE6xsputnEPKwl'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE7pubsyncEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE7seekoffExNS_8ios_base7seekdirEj'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE7seekposENS_4fposI11__mbstate_tEEj'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE7sungetcEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE8in_availEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE8overflowEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE8pubimbueERKNS_6localeE'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE9pbackfailEi'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE9pubsetbufEPwl'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE9showmanycEv'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE9sputbackcEw'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEE9underflowEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEEC1ERKS3_'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__215basic_streambufIwNS_11char_traitsIwEEEC1Ev'}
@@ -1198,13 +1107,11 @@
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD0Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD1Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__shared_weak_countD2Ev'}
-{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219__start_std_streamsE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219__thread_local_dataEv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__219declare_no_pointersEPcm'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__219piecewise_constructE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__get_collation_nameEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__220__throw_system_errorEiPKc'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__throw_runtime_errorEPKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221__undeclare_reachableEPv'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__221recursive_timed_mutex4lockEv'}
@@ -1481,10 +1388,6 @@
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__28time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 0}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZNSt3__28time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__28valarrayImE6resizeEmm'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__28valarrayImEC1Em'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__28valarrayImEC2Em'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__28valarrayImED1Ev'}
-{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__28valarrayImED2Ev'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__29__num_getIcE17__stage2_int_loopEciPcRS2_RjcRKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPjRSD_PKc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__29__num_getIcE17__stage2_int_prepERNS_8ios_baseERc'}
{'type': 'FUNC', 'is_defined': True, 'name': '__ZNSt3__29__num_getIcE19__stage2_float_loopEcRbRcPcRS4_ccRKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPjRSE_RjS4_'}
@@ -1806,8 +1709,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTISt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTISt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTISt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTISt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTISt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTISt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTISt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTISt16nested_exception', 'size': 0}
@@ -2098,8 +1999,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTSSt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTSSt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTSSt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTSSt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTSSt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTSSt16nested_exception', 'size': 0}
@@ -2291,8 +2190,6 @@
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt14overflow_error'}
{'type': 'U', 'is_defined': False, 'name': '__ZTVSt15underflow_error'}
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt15underflow_error'}
-{'type': 'U', 'is_defined': False, 'name': '__ZTVSt16bad_array_length'}
-{'type': 'I', 'is_defined': True, 'name': '__ZTVSt16bad_array_length'}
{'type': 'U', 'is_defined': False, 'name': '__ZTVSt16invalid_argument'}
{'type': 'I', 'is_defined': True, 'name': '__ZTVSt16invalid_argument'}
{'type': 'OBJECT', 'is_defined': True, 'name': '__ZTVSt16nested_exception', 'size': 0}
diff --git a/lib/abi/x86_64-unknown-linux-gnu.v1.abilist b/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
index 833342ca8992..0be9eb2fcb30 100644
--- a/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ b/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1098,13 +1098,11 @@
{'name': '_ZNSt3__119__shared_weak_countD0Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119__shared_weak_countD1Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119__shared_weak_countD2Ev', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__119__start_std_streamsE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
{'name': '_ZNSt3__119__thread_local_dataEv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119declare_no_pointersEPcm', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__119piecewise_constructE', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
{'name': '_ZNSt3__120__get_collation_nameEPKc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__120__throw_system_errorEiPKc', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE16__at_thread_exitEPv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121__throw_runtime_errorEPKc', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121__undeclare_reachableEPv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__121recursive_timed_mutex4lockEv', 'is_defined': True, 'type': 'FUNC'}
@@ -1125,8 +1123,6 @@
{'name': '_ZNSt3__124__libcpp_debug_exceptionD0Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__124__libcpp_debug_exceptionD1Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__124__libcpp_debug_exceptionD2Ev', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__125__num_get_signed_integralIlEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__125__num_get_signed_integralIxEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
@@ -1144,10 +1140,6 @@
{'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIxxEEPxEEbT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIyyEEPyEEbT0_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__127__libcpp_set_debug_functionEPFvRKNS_19__libcpp_debug_infoEE', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__127__num_get_unsigned_integralIjEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__127__num_get_unsigned_integralImEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__127__num_get_unsigned_integralItEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__127__num_get_unsigned_integralIyEET_PKcS3_Rji', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__129__libcpp_abort_debug_functionERKNS_19__libcpp_debug_infoE', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__129__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__13cinE', 'is_defined': True, 'type': 'OBJECT', 'size': 168}
@@ -1264,21 +1256,7 @@
{'name': '_ZNSt3__16thread6detachEv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__16threadD1Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__16threadD2Ev', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIaaEEPaEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIccEEPcEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIddEEPdEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__17__sort5IRNS_6__lessIeeEEPeEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIffEEPfEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIhhEEPhEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIiiEEPiEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIjjEEPjEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIllEEPlEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessImmEEPmEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIssEEPsEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIttEEPtEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIwwEEPwEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIxxEEPxEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__17__sort5IRNS_6__lessIyyEEPyEEjT0_S5_S5_S5_S5_T_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__17codecvtIDic11__mbstate_tE2idE', 'is_defined': True, 'type': 'OBJECT', 'size': 16}
{'name': '_ZNSt3__17codecvtIDic11__mbstate_tED0Ev', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__17codecvtIDic11__mbstate_tED1Ev', 'is_defined': True, 'type': 'FUNC'}
@@ -1449,7 +1427,6 @@
{'name': '_ZNSt3__19to_stringEx', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__19to_stringEy', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt3__1plIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_12basic_stringIT_T0_T1_EEPKS6_RKS9_', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZNSt3__1plIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_12basic_stringIT_T0_T1_EERKS9_PKS6_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZNSt8bad_castC1Ev', 'is_defined': False, 'type': 'FUNC'}
{'name': '_ZNSt8bad_castD1Ev', 'is_defined': False, 'type': 'FUNC'}
{'name': '_ZNSt8bad_castD2Ev', 'is_defined': False, 'type': 'FUNC'}
@@ -1460,7 +1437,6 @@
{'name': '_ZSt17__throw_bad_allocv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZSt17current_exceptionv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZSt17rethrow_exceptionSt13exception_ptr', 'is_defined': True, 'type': 'FUNC'}
-{'name': '_ZSt18make_exception_ptrINSt3__112future_errorEESt13exception_ptrT_', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZSt18uncaught_exceptionv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZSt19uncaught_exceptionsv', 'is_defined': True, 'type': 'FUNC'}
{'name': '_ZSt7nothrow', 'is_defined': True, 'type': 'OBJECT', 'size': 1}
diff --git a/lib/libc++abi2.exp b/lib/libc++abi2.exp
index 0059eb49e24e..40c055dae976 100644
--- a/lib/libc++abi2.exp
+++ b/lib/libc++abi2.exp
@@ -283,16 +283,6 @@ __ZTISt16invalid_argument
__ZTSSt16invalid_argument
__ZTVSt16invalid_argument
-__ZNKSt16bad_array_length4whatEv
-__ZNSt16bad_array_lengthC1Ev
-__ZNSt16bad_array_lengthC2Ev
-__ZNSt16bad_array_lengthD0Ev
-__ZNSt16bad_array_lengthD1Ev
-__ZNSt16bad_array_lengthD2Ev
-__ZTISt16bad_array_length
-__ZTSSt16bad_array_length
-__ZTVSt16bad_array_length
-
__ZTSDi
__ZTSDn
__ZTSDs
diff --git a/src/experimental/memory_resource.cpp b/src/experimental/memory_resource.cpp
index a3b64cc8b493..7f0052f2b50a 100644
--- a/src/experimental/memory_resource.cpp
+++ b/src/experimental/memory_resource.cpp
@@ -33,8 +33,9 @@ protected:
virtual void* do_allocate(size_t __size, size_t __align)
{ return _VSTD::__libcpp_allocate(__size, __align); /* FIXME */}
- virtual void do_deallocate(void * __p, size_t, size_t __align)
- { _VSTD::__libcpp_deallocate(__p, __align); /* FIXME */ }
+ virtual void do_deallocate(void* __p, size_t __n, size_t __align) {
+ _VSTD::__libcpp_deallocate(__p, __n, __align); /* FIXME */
+ }
virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
{ return &__other == this; }
diff --git a/src/filesystem/filesystem_common.h b/src/filesystem/filesystem_common.h
index ed92877c425c..40419ee35e6a 100644
--- a/src/filesystem/filesystem_common.h
+++ b/src/filesystem/filesystem_common.h
@@ -67,24 +67,31 @@ static string format_string_imp(const char* msg, ...) {
va_copy(args_cp, args);
GuardVAList args_copy_guard(args_cp);
+ std::string result;
+
array<char, 256> local_buff;
- size_t size = local_buff.size();
- auto ret = ::vsnprintf(local_buff.data(), size, msg, args_cp);
+ size_t size_with_null = local_buff.size();
+ auto ret = ::vsnprintf(local_buff.data(), size_with_null, msg, args_cp);
args_copy_guard.clear();
// handle empty expansion
if (ret == 0)
- return string{};
- if (static_cast<size_t>(ret) < size)
- return string(local_buff.data());
-
- // we did not provide a long enough buffer on our first attempt.
- // add 1 to size to account for null-byte in size cast to prevent overflow
- size = static_cast<size_t>(ret) + 1;
- auto buff_ptr = unique_ptr<char[]>(new char[size]);
- ret = ::vsnprintf(buff_ptr.get(), size, msg, args);
- return string(buff_ptr.get());
+ return result;
+ if (static_cast<size_t>(ret) < size_with_null) {
+ result.assign(local_buff.data(), static_cast<size_t>(ret));
+ return result;
+ }
+
+ // we did not provide a long enough buffer on our first attempt. The
+ // return value is the number of bytes (excluding the null byte) that are
+ // needed for formatting.
+ size_with_null = static_cast<size_t>(ret) + 1;
+ result.__resize_default_init(size_with_null - 1);
+ ret = ::vsnprintf(&result[0], size_with_null, msg, args);
+ _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
+
+ return result;
}
const char* unwrap(string const& s) { return s.c_str(); }
diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp
index 65a4b319339b..b41061888724 100644
--- a/src/filesystem/operations.cpp
+++ b/src/filesystem/operations.cpp
@@ -206,8 +206,20 @@ public:
return *this;
}
+ bool atEnd() const noexcept {
+ return State == PS_AtEnd;
+ }
+
+ bool inRootDir() const noexcept {
+ return State == PS_InRootDir;
+ }
+
+ bool inRootName() const noexcept {
+ return State == PS_InRootName;
+ }
+
bool inRootPath() const noexcept {
- return State == PS_InRootDir || State == PS_InRootName;
+ return inRootName() || inRootDir();
}
private:
@@ -352,7 +364,6 @@ struct FileDescriptor {
~FileDescriptor() { close(); }
- FileDescriptor() = default;
FileDescriptor(FileDescriptor const&) = delete;
FileDescriptor& operator=(FileDescriptor const&) = delete;
@@ -428,7 +439,8 @@ file_status posix_lstat(path const& p, error_code* ec) {
return posix_lstat(p, path_stat, ec);
}
-bool posix_ftruncate(const FileDescriptor& fd, size_t to_size, error_code& ec) {
+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
+bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
if (::ftruncate(fd.fd, to_size) == -1) {
ec = capture_errno();
return true;
@@ -1295,7 +1307,19 @@ string_view_t path::__root_path_raw() const {
return {};
}
+static bool ConsumeRootName(PathParser *PP) {
+ static_assert(PathParser::PS_BeforeBegin == 1 &&
+ PathParser::PS_InRootName == 2,
+ "Values for enums are incorrect");
+ while (PP->State <= PathParser::PS_InRootName)
+ ++(*PP);
+ return PP->State == PathParser::PS_AtEnd;
+}
+
static bool ConsumeRootDir(PathParser* PP) {
+ static_assert(PathParser::PS_BeforeBegin == 1 &&
+ PathParser::PS_InRootName == 2 &&
+ PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
while (PP->State <= PathParser::PS_InRootDir)
++(*PP);
return PP->State == PathParser::PS_AtEnd;
@@ -1455,7 +1479,7 @@ static int DetermineLexicalElementCount(PathParser PP) {
auto Elem = *PP;
if (Elem == "..")
--Count;
- else if (Elem != ".")
+ else if (Elem != "." && Elem != "")
++Count;
}
return Count;
@@ -1469,8 +1493,7 @@ path path::lexically_relative(const path& base) const {
return PP.State != PPBase.State &&
(PP.inRootPath() || PPBase.inRootPath());
};
- if (PP.State == PathParser::PS_InRootName &&
- PPBase.State == PathParser::PS_InRootName) {
+ if (PP.inRootName() && PPBase.inRootName()) {
if (*PP != *PPBase)
return {};
} else if (CheckIterMismatchAtBase())
@@ -1502,6 +1525,10 @@ path path::lexically_relative(const path& base) const {
if (ElemCount < 0)
return {};
+ // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
+ if (ElemCount == 0 && (PP.atEnd() || *PP == ""))
+ return ".";
+
// return a path constructed with 'n' dot-dot elements, followed by the the
// elements of '*this' after the mismatch.
path Result;
@@ -1515,21 +1542,68 @@ path path::lexically_relative(const path& base) const {
////////////////////////////////////////////////////////////////////////////
// path.comparisons
-int path::__compare(string_view_t __s) const {
- auto PP = PathParser::CreateBegin(__pn_);
- auto PP2 = PathParser::CreateBegin(__s);
- while (PP && PP2) {
- int res = (*PP).compare(*PP2);
- if (res != 0)
+static int CompareRootName(PathParser *LHS, PathParser *RHS) {
+ if (!LHS->inRootName() && !RHS->inRootName())
+ return 0;
+
+ auto GetRootName = [](PathParser *Parser) -> string_view_t {
+ return Parser->inRootName() ? **Parser : "";
+ };
+ int res = GetRootName(LHS).compare(GetRootName(RHS));
+ ConsumeRootName(LHS);
+ ConsumeRootName(RHS);
+ return res;
+}
+
+static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
+ if (!LHS->inRootDir() && RHS->inRootDir())
+ return -1;
+ else if (LHS->inRootDir() && !RHS->inRootDir())
+ return 1;
+ else {
+ ConsumeRootDir(LHS);
+ ConsumeRootDir(RHS);
+ return 0;
+ }
+}
+
+static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
+ auto &LHS = *LHSPtr;
+ auto &RHS = *RHSPtr;
+
+ int res;
+ while (LHS && RHS) {
+ if ((res = (*LHS).compare(*RHS)) != 0)
return res;
- ++PP;
- ++PP2;
+ ++LHS;
+ ++RHS;
}
- if (PP.State == PP2.State && !PP)
- return 0;
- if (!PP)
+ return 0;
+}
+
+static int CompareEndState(PathParser *LHS, PathParser *RHS) {
+ if (LHS->atEnd() && !RHS->atEnd())
return -1;
- return 1;
+ else if (!LHS->atEnd() && RHS->atEnd())
+ return 1;
+ return 0;
+}
+
+int path::__compare(string_view_t __s) const {
+ auto LHS = PathParser::CreateBegin(__pn_);
+ auto RHS = PathParser::CreateBegin(__s);
+ int res;
+
+ if ((res = CompareRootName(&LHS, &RHS)) != 0)
+ return res;
+
+ if ((res = CompareRootDir(&LHS, &RHS)) != 0)
+ return res;
+
+ if ((res = CompareRelative(&LHS, &RHS)) != 0)
+ return res;
+
+ return CompareEndState(&LHS, &RHS);
}
////////////////////////////////////////////////////////////////////////////
diff --git a/src/future.cpp b/src/future.cpp
index 07e4602f567f..cbcd2e7b7288 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -179,10 +179,7 @@ __assoc_sub_state::__execute()
future<void>::future(__assoc_sub_state* __state)
: __state_(__state)
{
- if (__state_->__has_future_attached())
- __throw_future_error(future_errc::future_already_retrieved);
- __state_->__add_shared();
- __state_->__set_future_attached();
+ __state_->__attach_future();
}
future<void>::~future()
diff --git a/src/iostream.cpp b/src/iostream.cpp
index 2b47cf25b640..11bfb486208e 100644
--- a/src/iostream.cpp
+++ b/src/iostream.cpp
@@ -13,21 +13,21 @@
#define _str(s) #s
#define str(s) _str(s)
-#define _LIBCPP_NAMESPACE_STR str(_LIBCPP_NAMESPACE)
+#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_STDIN
_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?cin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)];
static mbstate_t mb_cin;
_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?wcin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar_t>)];
@@ -37,14 +37,14 @@ static mbstate_t mb_wcin;
#ifndef _LIBCPP_HAS_NO_STDOUT
_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?cout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
static mbstate_t mb_cout;
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?wcout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
@@ -53,14 +53,14 @@ static mbstate_t mb_wcout;
_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?cerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
static mbstate_t mb_cerr;
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?wcerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
@@ -68,16 +68,16 @@ static mbstate_t mb_wcerr;
_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?clog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)]
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-__asm__("?wclog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A")
+__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A")
#endif
;
-ios_base::Init __start_std_streams;
+_LIBCPP_HIDDEN ios_base::Init __start_std_streams;
ios_base::Init::Init()
{
diff --git a/src/new.cpp b/src/new.cpp
index 8013d89ae3c2..cc8383d4f146 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -55,7 +55,7 @@ __throw_bad_alloc()
} // std
#if !defined(__GLIBCXX__) && \
- (!defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)) && \
+ !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) && \
!defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
// Implement all new and delete operators as weak definitions
@@ -135,8 +135,7 @@ _LIBCPP_WEAK
void
operator delete(void* ptr) _NOEXCEPT
{
- if (ptr)
- ::free(ptr);
+ ::free(ptr);
}
_LIBCPP_WEAK
@@ -174,7 +173,7 @@ operator delete[] (void* ptr, size_t) _NOEXCEPT
::operator delete[](ptr);
}
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
_LIBCPP_WEAK
void *
@@ -257,11 +256,10 @@ _LIBCPP_WEAK
void
operator delete(void* ptr, std::align_val_t) _NOEXCEPT
{
- if (ptr)
#if defined(_LIBCPP_MSVCRT_LIKE)
- ::_aligned_free(ptr);
+ ::_aligned_free(ptr);
#else
- ::free(ptr);
+ ::free(ptr);
#endif
}
@@ -300,5 +298,5 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
::operator delete[](ptr, alignment);
}
-#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
#endif // !__GLIBCXX__ && (!_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME) && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
diff --git a/src/support/runtime/exception_fallback.ipp b/src/support/runtime/exception_fallback.ipp
index 664e7f48c09a..16d387b99e8c 100644
--- a/src/support/runtime/exception_fallback.ipp
+++ b/src/support/runtime/exception_fallback.ipp
@@ -134,22 +134,6 @@ bad_array_new_length::what() const _NOEXCEPT
return "bad_array_new_length";
}
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
-
bad_cast::bad_cast() _NOEXCEPT
{
}
diff --git a/src/support/runtime/exception_glibcxx.ipp b/src/support/runtime/exception_glibcxx.ipp
index 0f78932f6f98..dda4432b508a 100644
--- a/src/support/runtime/exception_glibcxx.ipp
+++ b/src/support/runtime/exception_glibcxx.ipp
@@ -22,11 +22,6 @@ bad_array_new_length::bad_array_new_length() _NOEXCEPT
{
}
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-
bad_cast::bad_cast() _NOEXCEPT
{
}
diff --git a/src/support/runtime/exception_libcxxrt.ipp b/src/support/runtime/exception_libcxxrt.ipp
index 6d9e0cff58dc..52fe8635db77 100644
--- a/src/support/runtime/exception_libcxxrt.ipp
+++ b/src/support/runtime/exception_libcxxrt.ipp
@@ -23,19 +23,4 @@ const char* bad_exception::what() const _NOEXCEPT
return "std::bad_exception";
}
-
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
} // namespace std
diff --git a/src/support/runtime/exception_msvc.ipp b/src/support/runtime/exception_msvc.ipp
index 87d5a66fc8f9..042d3add6c7f 100644
--- a/src/support/runtime/exception_msvc.ipp
+++ b/src/support/runtime/exception_msvc.ipp
@@ -83,20 +83,6 @@ int uncaught_exceptions() _NOEXCEPT {
return __uncaught_exceptions();
}
-bad_array_length::bad_array_length() _NOEXCEPT
-{
-}
-
-bad_array_length::~bad_array_length() _NOEXCEPT
-{
-}
-
-const char*
-bad_array_length::what() const _NOEXCEPT
-{
- return "bad_array_length";
-}
-
#if defined(_LIBCPP_NO_VCRUNTIME)
bad_cast::bad_cast() _NOEXCEPT
{
diff --git a/src/thread.cpp b/src/thread.cpp
index 550da8ea71f3..241cfee23c5b 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -19,9 +19,9 @@
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# include <sys/param.h>
-# if defined(BSD)
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__)
# include <sys/sysctl.h>
-# endif // defined(BSD)
+# endif
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) || defined(__Fuchsia__)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f8442460a2fe..9435744d3c81 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -55,17 +55,8 @@ set(LIBCXX_EXECUTOR "None" CACHE STRING
set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
-set(LIBCXX_TEST_DEPS "")
-
-if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
- list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
-endif()
-if (LIBCXX_ENABLE_FILESYSTEM)
- list(APPEND LIBCXX_TEST_DEPS cxx_filesystem)
-endif()
-
-if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
- list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
+if (NOT DEFINED LIBCXX_TEST_DEPS)
+ message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
endif()
if (LIBCXX_INCLUDE_TESTS)
diff --git a/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
index 28a9281b49c2..58ce689981ca 100644
--- a/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
+++ b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// <memory>
+// <algorithm>
// template <class RandomAccessIterator>
// void
@@ -23,6 +23,8 @@
// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
// is defined before including <algorithm>, then random_shuffle will be restored.
+// REQUIRES: verify-support
+
// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
diff --git a/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.fail.cpp b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.fail.cpp
new file mode 100644
index 000000000000..608f4f86c31f
--- /dev/null
+++ b/test/libcxx/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.fail.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class RandomAccessIterator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last);
+//
+// template <class RandomAccessIterator, class RandomNumberGenerator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+// RandomNumberGenerator& rand);
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+
+#include <algorithm>
+#include <cstddef>
+
+#include "test_macros.h"
+
+struct gen
+{
+ std::ptrdiff_t operator()(std::ptrdiff_t n)
+ {
+ return n-1;
+ }
+};
+
+
+int main()
+{
+ int v[1] = {1};
+ std::random_shuffle(&v[0], &v[1]); // expected-error{{'random_shuffle<int *>' is deprecated}}
+ gen r;
+ std::random_shuffle(&v[0], &v[1], r); // expected-error{{'random_shuffle<int *, gen &>' is deprecated}}
+}
diff --git a/test/libcxx/algorithms/debug_less.pass.cpp b/test/libcxx/algorithms/debug_less.pass.cpp
index e030f64e5dd9..302c5a8376c8 100644
--- a/test/libcxx/algorithms/debug_less.pass.cpp
+++ b/test/libcxx/algorithms/debug_less.pass.cpp
@@ -161,7 +161,58 @@ void test_failing() {
}
}
+template <int>
+struct Tag {
+ explicit Tag(int v) : value(v) {}
+ int value;
+};
+
+template <class = void>
+struct FooImp {
+ explicit FooImp(int x) : x_(x) {}
+ int x_;
+};
+
+template <class T>
+inline bool operator<(FooImp<T> const& x, Tag<0> y) {
+ return x.x_ < y.value;
+}
+
+template <class T>
+inline bool operator<(Tag<0>, FooImp<T> const&) {
+ static_assert(sizeof(FooImp<T>) != sizeof(FooImp<T>), "should not be instantiated");
+}
+
+template <class T>
+inline bool operator<(Tag<1> x, FooImp<T> const& y) {
+ return x.value < y.x_;
+}
+
+template <class T>
+inline bool operator<(FooImp<T> const&, Tag<1>) {
+ static_assert(sizeof(FooImp<T>) != sizeof(FooImp<T>), "should not be instantiated");
+}
+
+typedef FooImp<> Foo;
+
+// Test that we don't attempt to call the comparator with the arguments reversed
+// for upper_bound and lower_bound since the comparator or type is not required
+// to support it, nor does it require the range to have a strict weak ordering.
+// See llvm.org/PR39458
+void test_upper_and_lower_bound() {
+ Foo table[] = {Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)};
+ {
+ Foo* iter = std::lower_bound(std::begin(table), std::end(table), Tag<0>(3));
+ assert(iter == (table + 2));
+ }
+ {
+ Foo* iter = std::upper_bound(std::begin(table), std::end(table), Tag<1>(3));
+ assert(iter == (table + 3));
+ }
+}
+
int main() {
test_passing();
test_failing();
+ test_upper_and_lower_bound();
}
diff --git a/test/libcxx/algorithms/half_positive.pass.cpp b/test/libcxx/algorithms/half_positive.pass.cpp
new file mode 100644
index 000000000000..7dcfc2c92c94
--- /dev/null
+++ b/test/libcxx/algorithms/half_positive.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// __half_positive divides an integer number by 2 as unsigned number for known types.
+// It can be an important optimization for lower bound, for example.
+
+#include <algorithm>
+#include <cassert>
+#include <limits>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "user_defined_integral.hpp"
+
+namespace {
+
+template <class IntType, class UnderlyingType = IntType>
+TEST_CONSTEXPR bool test(IntType max_v = IntType(std::numeric_limits<UnderlyingType>::max())) {
+ return std::__half_positive(max_v) == max_v / 2;
+}
+
+} // namespace
+
+int main()
+{
+ {
+ assert(test<char>());
+ assert(test<int>());
+ assert(test<long>());
+ assert((test<UserDefinedIntegral<int>, int>()));
+ assert(test<size_t>());
+#if !defined(_LIBCPP_HAS_NO_INT128)
+ assert(test<__int128_t>());
+#endif // !defined(_LIBCPP_HAS_NO_INT128)
+ }
+
+#if TEST_STD_VER >= 11
+ {
+ static_assert(test<char>(), "");
+ static_assert(test<int>(), "");
+ static_assert(test<long>(), "");
+ static_assert(test<size_t>(), "");
+#if !defined(_LIBCPP_HAS_NO_INT128)
+ static_assert(test<__int128_t>(), "");
+#endif // !defined(_LIBCPP_HAS_NO_INT128)
+ }
+#endif // TEST_STD_VER >= 11
+}
diff --git a/test/libcxx/containers/associative/non_const_comparator.fail.cpp b/test/libcxx/containers/associative/non_const_comparator.fail.cpp
index ea0d9ac09328..ddd796089399 100644
--- a/test/libcxx/containers/associative/non_const_comparator.fail.cpp
+++ b/test/libcxx/containers/associative/non_const_comparator.fail.cpp
@@ -27,7 +27,8 @@ int main() {
static_assert(!std::__invokable<BadCompare const&, int const&, int const&>::value, "");
static_assert(std::__invokable<BadCompare&, int const&, int const&>::value, "");
- // expected-warning@__tree:* 4 {{the specified comparator type does not provide a const call operator}}
+ // expected-warning@set:* 2 {{the specified comparator type does not provide a const call operator}}
+ // expected-warning@map:* 2 {{the specified comparator type does not provide a const call operator}}
{
using C = std::set<int, BadCompare>;
C s;
diff --git a/test/libcxx/type_traits/is_floating_point.pass.cpp b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp
index 98452fad384b..e4f5d0b01197 100644
--- a/test/libcxx/type_traits/is_floating_point.pass.cpp
+++ b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp
@@ -6,19 +6,21 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// <type_traits>
-//
-// Test that is_floating_point<T>::value is true when T=__fp16 or T=_Float16.
-#include <type_traits>
+// <deque>
+
+// pop_back() more than the number of elements in a deque
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <cstdlib>
+#include <deque>
+
int main() {
-#ifdef __clang__
- static_assert(std::is_floating_point<__fp16>::value, "");
-#endif
-#ifdef __FLT16_MANT_DIG__
- static_assert(std::is_floating_point<_Float16>::value, "");
-#endif
- return 0;
+ std::deque<int> q;
+ q.push_back(0);
+ q.pop_back();
+ q.pop_back();
+ std::exit(1);
}
diff --git a/test/libcxx/containers/sequences/vector/db_back.pass.cpp b/test/libcxx/containers/sequences/vector/db_back.pass.cpp
index 05f3d07712eb..d66ffeb67af0 100644
--- a/test/libcxx/containers/sequences/vector/db_back.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_back.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
assert(c.back() == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_cback.pass.cpp b/test/libcxx/containers/sequences/vector/db_cback.pass.cpp
index 5eb1a353e8b0..9ad0fb92969f 100644
--- a/test/libcxx/containers/sequences/vector/db_cback.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_cback.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -32,7 +33,7 @@ int main()
assert(c.back() == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp b/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp
index 5e54da1d444e..58f57a500dd9 100644
--- a/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_cfront.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -32,7 +33,7 @@ int main()
assert(c.front() == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp b/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp
index 133aa5652824..9a54b6cb9842 100644
--- a/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_cindex.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -33,7 +34,7 @@ int main()
assert(c[1] == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_front.pass.cpp b/test/libcxx/containers/sequences/vector/db_front.pass.cpp
index 388058fb3159..0acb7df0c4d9 100644
--- a/test/libcxx/containers/sequences/vector/db_front.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_front.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
assert(c.front() == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_index.pass.cpp b/test/libcxx/containers/sequences/vector/db_index.pass.cpp
index 1daf076da67c..75ae095f2b1c 100644
--- a/test/libcxx/containers/sequences/vector/db_index.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_index.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
assert(c[0] == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp
index 2d43843067b7..d5e8c86109b7 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_2.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -33,7 +34,7 @@ int main()
bool b = c1.begin() < c2.begin();
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp
index 051d66c33394..96a75204a7bd 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_3.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -33,7 +34,7 @@ int main()
int i = c1.begin() - c2.begin();
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp
index 4c2aa628de14..311a517cfc01 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_4.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
assert(i[1] == 0);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp
index 1b1090499c27..6df3fd459c18 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_5.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,7 +37,7 @@ int main()
i += 2;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp
index 424bc939b136..0785dd96444c 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_6.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -35,7 +36,7 @@ int main()
--i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp
index 72cdb10cbc85..11ba9f864b0c 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_7.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -35,7 +36,7 @@ int main()
++i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp b/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp
index 7b898533197c..0434ad5f1509 100644
--- a/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/db_iterators_8.pass.cpp
@@ -21,6 +21,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -33,7 +34,7 @@ int main()
T j = *i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
diff --git a/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp
new file mode 100644
index 000000000000..388dfa4e1a83
--- /dev/null
+++ b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// pop_back() more than the number of elements in a vector
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <cstdlib>
+#include <vector>
+
+
+int main() {
+ std::vector<int> v;
+ v.push_back(0);
+ v.pop_back();
+ v.pop_back();
+ std::exit(1);
+}
diff --git a/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
new file mode 100644
index 000000000000..998d0b74eddf
--- /dev/null
+++ b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class InputIter> vector(InputIter first, InputIter last);
+
+#include <vector>
+#include <cassert>
+
+#include "min_allocator.h"
+
+void test_ctor_under_alloc() {
+ int arr1[] = {42};
+ int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+}
+
+int main() {
+ test_ctor_under_alloc();
+}
diff --git a/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
new file mode 100644
index 000000000000..c4950fbe637d
--- /dev/null
+++ b/test/libcxx/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class InputIter> vector(InputIter first, InputIter last,
+// const allocator_type& a);
+
+#include <vector>
+#include <cassert>
+
+#include "min_allocator.h"
+
+void test_ctor_under_alloc() {
+ int arr1[] = {42};
+ int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+}
+
+int main() {
+ test_ctor_under_alloc();
+}
diff --git a/test/libcxx/containers/unord/non_const_comparator.fail.cpp b/test/libcxx/containers/unord/non_const_comparator.fail.cpp
index 8adc67589ef8..f428ab9aca6d 100644
--- a/test/libcxx/containers/unord/non_const_comparator.fail.cpp
+++ b/test/libcxx/containers/unord/non_const_comparator.fail.cpp
@@ -11,7 +11,7 @@
// REQUIRES: diagnose-if-support, verify-support
// Test that libc++ generates a warning diagnostic when the container is
-// provided a non-const callable comparator.
+// provided a non-const callable comparator or a non-const hasher.
#include <unordered_set>
#include <unordered_map>
@@ -34,8 +34,10 @@ int main() {
static_assert(!std::__invokable<BadEqual const&, int const&, int const&>::value, "");
static_assert(std::__invokable<BadEqual&, int const&, int const&>::value, "");
- // expected-warning@__hash_table:* 4 {{the specified comparator type does not provide a const call operator}}
- // expected-warning@__hash_table:* 4 {{the specified hash functor does not provide a const call operator}}
+ // expected-warning@unordered_set:* 2 {{the specified comparator type does not provide a const call operator}}
+ // expected-warning@unordered_map:* 2 {{the specified comparator type does not provide a const call operator}}
+ // expected-warning@unordered_set:* 2 {{the specified hash functor does not provide a const call operator}}
+ // expected-warning@unordered_map:* 2 {{the specified hash functor does not provide a const call operator}}
{
using C = std::unordered_set<int, BadHash, BadEqual>;
diff --git a/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp b/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp
index b8db0a35ffc3..664cb7e86b95 100644
--- a/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp
+++ b/test/libcxx/containers/unord/unord.map/db_iterators_7.pass.cpp
@@ -22,6 +22,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,7 +37,7 @@ int main()
++i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
diff --git a/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp b/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp
index c923dd77862e..621d7f343e08 100644
--- a/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp
+++ b/test/libcxx/containers/unord/unord.map/db_iterators_8.pass.cpp
@@ -22,6 +22,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
C::value_type j = *i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
diff --git a/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp b/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp
index fa1886bfff18..19794e04769d 100644
--- a/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp
+++ b/test/libcxx/containers/unord/unord.map/db_local_iterators_7.pass.cpp
@@ -22,6 +22,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -34,7 +35,7 @@ int main()
++i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
diff --git a/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp b/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp
index 4b071cad7b47..1567caf9be9e 100644
--- a/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp
+++ b/test/libcxx/containers/unord/unord.map/db_local_iterators_8.pass.cpp
@@ -22,6 +22,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -33,7 +34,7 @@ int main()
C::value_type j = *i;
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
diff --git a/test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp b/test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..3ad9ae8d6f68
--- /dev/null
+++ b/test/libcxx/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+//
+// template <class X>
+// class auto_ptr;
+//
+// class auto_ptr<void>;
+//
+// template <class X>
+// class auto_ptr_ref;
+//
+// Deprecated in C++11
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+
+#include <memory>
+#include "test_macros.h"
+
+int main()
+{
+ typedef std::auto_ptr<int> AP; // expected-error{{'auto_ptr<int>' is deprecated}}
+ typedef std::auto_ptr<void> APV; // expected-error{{'auto_ptr<void>' is deprecated}}
+ typedef std::auto_ptr_ref<int> APR; // expected-error{{'auto_ptr_ref<int>' is deprecated}}
+}
diff --git a/test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.fail.cpp b/test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..88c1e21d6bb6
--- /dev/null
+++ b/test/libcxx/depr/depr.function.objects/adaptors.depr_in_cxx11.fail.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+#include <cassert>
+#include "test_macros.h"
+
+int identity(int v) { return v; }
+int sum(int a, int b) { return a + b; }
+
+struct Foo {
+ int const_zero() const { return 0; }
+ int const_identity(int v) const { return v; }
+ int zero() { return 0; }
+ int identity(int v) { return v; }
+};
+
+int main()
+{
+ typedef std::pointer_to_unary_function<int, int> PUF; // expected-error{{'pointer_to_unary_function<int, int>' is deprecated}}
+ typedef std::pointer_to_binary_function<int, int, int> PBF; // expected-error{{'pointer_to_binary_function<int, int, int>' is deprecated}}
+ std::ptr_fun<int, int>(identity); // expected-error{{'ptr_fun<int, int>' is deprecated}}
+ std::ptr_fun<int, int, int>(sum); // expected-error{{'ptr_fun<int, int, int>' is deprecated}}
+
+ typedef std::mem_fun_t<int, Foo> MFT0; // expected-error{{'mem_fun_t<int, Foo>' is deprecated}}
+ typedef std::mem_fun1_t<int, Foo, int> MFT1; // expected-error{{'mem_fun1_t<int, Foo, int>' is deprecated}}
+ typedef std::const_mem_fun_t<int, Foo> CMFT0; // expected-error{{'const_mem_fun_t<int, Foo>' is deprecated}}
+ typedef std::const_mem_fun1_t<int, Foo, int> CMFT1; // expected-error{{'const_mem_fun1_t<int, Foo, int>' is deprecated}}
+ std::mem_fun<int, Foo>(&Foo::zero); // expected-error{{'mem_fun<int, Foo>' is deprecated}}
+ std::mem_fun<int, Foo, int>(&Foo::identity); // expected-error{{'mem_fun<int, Foo, int>' is deprecated}}
+ std::mem_fun<int, Foo>(&Foo::const_zero); // expected-error{{'mem_fun<int, Foo>' is deprecated}}
+ std::mem_fun<int, Foo, int>(&Foo::const_identity); // expected-error{{'mem_fun<int, Foo, int>' is deprecated}}
+
+ typedef std::mem_fun_ref_t<int, Foo> MFR0; // expected-error{{'mem_fun_ref_t<int, Foo>' is deprecated}}
+ typedef std::mem_fun1_ref_t<int, Foo, int> MFR1; // expected-error{{'mem_fun1_ref_t<int, Foo, int>' is deprecated}}
+ typedef std::const_mem_fun_ref_t<int, Foo> CMFR0; // expected-error{{'const_mem_fun_ref_t<int, Foo>' is deprecated}}
+ typedef std::const_mem_fun1_ref_t<int, Foo, int> CMFR1; // expected-error{{'const_mem_fun1_ref_t<int, Foo, int>' is deprecated}}
+ std::mem_fun_ref<int, Foo>(&Foo::zero); // expected-error{{'mem_fun_ref<int, Foo>' is deprecated}}
+ std::mem_fun_ref<int, Foo, int>(&Foo::identity); // expected-error{{'mem_fun_ref<int, Foo, int>' is deprecated}}
+ std::mem_fun_ref<int, Foo>(&Foo::const_zero); // expected-error{{'mem_fun_ref<int, Foo>' is deprecated}}
+ std::mem_fun_ref<int, Foo, int>(&Foo::const_identity); // expected-error{{'mem_fun_ref<int, Foo, int>' is deprecated}}
+}
diff --git a/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp b/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
index 1847dac2ed00..beb560800612 100644
--- a/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
+++ b/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
@@ -24,15 +24,25 @@ int identity(int v) { return v; }
int sum(int a, int b) { return a + b; }
struct Foo {
- int zero() const { return 0; }
- int identity(int v) const { return v; }
- int sum(int a, int b) const { return a + b; }
+ int zero() { return 0; }
+ int zero_const() const { return 1; }
+
+ int identity(int v) const { return v; }
+ int sum(int a, int b) const { return a + b; }
};
int main()
{
typedef std::pointer_to_unary_function<int, int> PUF;
typedef std::pointer_to_binary_function<int, int, int> PBF;
+
+ static_assert(
+ (std::is_same<PUF, decltype((std::ptr_fun<int, int>(identity)))>::value),
+ "");
+ static_assert(
+ (std::is_same<PBF, decltype((std::ptr_fun<int, int, int>(sum)))>::value),
+ "");
+
assert((std::ptr_fun<int, int>(identity)(4) == 4));
assert((std::ptr_fun<int, int, int>(sum)(4, 5) == 9));
@@ -43,6 +53,12 @@ int main()
typedef std::mem_fun_ref_t<int, Foo> MFR;
typedef std::const_mem_fun_ref_t<int, Foo> CMFR;
+ static_assert(
+ (std::is_same<MFR, decltype((std::mem_fun_ref(&Foo::zero)))>::value), "");
+ static_assert((std::is_same<CMFR, decltype((std::mem_fun_ref(
+ &Foo::zero_const)))>::value),
+ "");
+
assert((std::mem_fun_ref(&Foo::zero)(f) == 0));
assert((std::mem_fun_ref(&Foo::identity)(f, 5) == 5));
}
diff --git a/test/libcxx/diagnostics/enable_nodiscard.fail.cpp b/test/libcxx/diagnostics/enable_nodiscard.fail.cpp
new file mode 100644
index 000000000000..e1ef17672ccb
--- /dev/null
+++ b/test/libcxx/diagnostics/enable_nodiscard.fail.cpp
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that _LIBCPP_NODISCARD_EXT and _LIBCPP_NODISCARD_AFTER_CXX17 are defined
+// to the appropriate warning-generating attribute when _LIBCPP_ENABLE_NODISCARD
+// is explicitly provided.
+
+// UNSUPPORTED: c++98, c++03
+
+// GCC 7 is the first version to introduce [[nodiscard]]
+// UNSUPPORTED: gcc-4.9, gcc-5, gcc-6
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_NODISCARD
+#define _LIBCPP_ENABLE_NODISCARD
+
+#include <__config>
+
+_LIBCPP_NODISCARD_EXT int foo() { return 42; }
+_LIBCPP_NODISCARD_AFTER_CXX17 int bar() { return 42; }
+
+int main() {
+ foo(); // expected-error-re {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
+ bar(); // expected-error-re {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
+ (void)foo(); // OK. void casts disable the diagnostic.
+ (void)bar();
+}
diff --git a/test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.fail.cpp b/test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.fail.cpp
new file mode 100644
index 000000000000..2c7d899ff5a0
--- /dev/null
+++ b/test/libcxx/diagnostics/enable_nodiscard_disable_after_cxx17.fail.cpp
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// GCC 7 is the first version to introduce [[nodiscard]]
+// UNSUPPORTED: gcc-4.9, gcc-5, gcc-6
+
+// Test that _LIBCPP_DISABLE_NODISCARD_EXT only disables _LIBCPP_NODISCARD_EXT
+// and not _LIBCPP_NODISCARD_AFTER_CXX17.
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_NODISCARD
+// MODULES_DEFINES: _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
+#define _LIBCPP_ENABLE_NODISCARD
+#define _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
+#include <__config>
+
+
+_LIBCPP_NODISCARD_EXT int foo() { return 42; }
+_LIBCPP_NODISCARD_AFTER_CXX17 int bar() { return 42; }
+
+int main() {
+ foo(); // expected-error-re {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
+ bar(); // OK.
+ (void)foo(); // OK.
+}
diff --git a/test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.fail.cpp b/test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.fail.cpp
new file mode 100644
index 000000000000..c7d080d8425c
--- /dev/null
+++ b/test/libcxx/diagnostics/enable_nodiscard_disable_nodiscard_ext.fail.cpp
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// GCC 7 is the first version to introduce [[nodiscard]]
+// UNSUPPORTED: gcc-4.9, gcc-5, gcc-6
+
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_NODISCARD
+// MODULES_DEFINES: _LIBCPP_DISABLE_NODISCARD_EXT
+#define _LIBCPP_ENABLE_NODISCARD
+#define _LIBCPP_DISABLE_NODISCARD_EXT
+#include <__config>
+
+
+_LIBCPP_NODISCARD_EXT int foo() { return 42; }
+_LIBCPP_NODISCARD_AFTER_CXX17 int bar() { return 42; }
+
+int main() {
+ bar(); // expected-error-re {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
+ foo(); // OK.
+ (void)bar(); // OK.
+}
diff --git a/test/libcxx/diagnostics/nodiscard.pass.cpp b/test/libcxx/diagnostics/nodiscard.pass.cpp
index d308248cff22..de920d459ed6 100644
--- a/test/libcxx/diagnostics/nodiscard.pass.cpp
+++ b/test/libcxx/diagnostics/nodiscard.pass.cpp
@@ -8,18 +8,13 @@
//
//===----------------------------------------------------------------------===//
-// Test that _LIBCPP_NODISCARD_AFTER_CXX17 works
-// #define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]]
+// Test that _LIBCPP_NODISCARD_EXT is not defined to [[nodiscard]] unless
+// explicitly enabled by _LIBCPP_ENABLE_NODISCARD
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-
-// MODULES_DEFINES: _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
-#define _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
#include <__config>
-_LIBCPP_NODISCARD_AFTER_CXX17 int foo() { return 6; }
+_LIBCPP_NODISCARD_EXT int foo() { return 42; }
-int main ()
-{
- foo(); // no error here!
+int main() {
+ foo(); // OK.
}
diff --git a/test/libcxx/diagnostics/nodiscard.fail.cpp b/test/libcxx/diagnostics/nodiscard_aftercxx17.fail.cpp
index 903a24a72805..47e560feb962 100644
--- a/test/libcxx/diagnostics/nodiscard.fail.cpp
+++ b/test/libcxx/diagnostics/nodiscard_aftercxx17.fail.cpp
@@ -12,7 +12,6 @@
// #define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]]
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
#include <__config>
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/libcxx/diagnostics/nodiscard_aftercxx17.pass.cpp
index 48da6d885773..4db8181723e1 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
+++ b/test/libcxx/diagnostics/nodiscard_aftercxx17.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -7,22 +8,16 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11
-// dynarray.data
-
-// template <class Type, class Alloc>
-// struct uses_allocator<dynarray<Type>, Alloc> : true_type { };
-
+// Test that _LIBCPP_NODISCARD_AFTER_CXX17 is disabled whenever
+// _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17 is defined by the user.
+// MODULES_DEFINES: _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
+#define _LIBCPP_DISABLE_NODISCARD_AFTER_CXX17
#include <__config>
-#include <experimental/dynarray>
-#include "test_allocator.h"
+_LIBCPP_NODISCARD_AFTER_CXX17 int foo() { return 6; }
-using std::experimental::dynarray;
-
-int main()
+int main ()
{
- static_assert ( std::uses_allocator<dynarray<int>, test_allocator<int>>::value, "" );
+ foo(); // no error here!
}
-
diff --git a/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp b/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp
new file mode 100644
index 000000000000..d1e0a8af5c8a
--- /dev/null
+++ b/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// GCC versions prior to 7.0 don't provide the required [[nodiscard]] attribute.
+// UNSUPPORTED: gcc-4, gcc-5, gcc-6
+
+// Test that entities declared [[nodiscard]] as at extension by libc++, are
+// only actually declared such when _LIBCPP_ENABLE_NODISCARD is specified.
+
+// All entities to which libc++ applies [[nodiscard]] as an extension should
+// be tested here and in nodiscard_extensions.pass.cpp. They should also
+// be listed in `UsingLibcxx.rst` in the documentation for the extension.
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_NODISCARD
+#define _LIBCPP_ENABLE_NODISCARD
+
+#include <memory>
+
+#include "test_macros.h"
+
+int main() {
+ {
+ // expected-error-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
+ std::get_temporary_buffer<int>(1);
+ }
+}
diff --git a/test/libcxx/diagnostics/nodiscard_extensions.pass.cpp b/test/libcxx/diagnostics/nodiscard_extensions.pass.cpp
new file mode 100644
index 000000000000..9a09a43bae1c
--- /dev/null
+++ b/test/libcxx/diagnostics/nodiscard_extensions.pass.cpp
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that entities declared [[nodiscard]] as at extension by libc++, are
+// only actually declared such when _LIBCPP_ENABLE_NODISCARD is specified.
+
+// This test intentionally leaks memory, so it is unsupported under ASAN.
+// UNSUPPORTED: asan
+
+// All entities to which libc++ applies [[nodiscard]] as an extension should
+// be tested here and in nodiscard_extensions.fail.cpp. They should also
+// be listed in `UsingLibcxx.rst` in the documentation for the extension.
+
+#include <memory>
+
+#include "test_macros.h"
+
+int main() {
+ {
+ std::get_temporary_buffer<int>(1); // intentional memory leak.
+ }
+}
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index 8d08db4fd105..5a0f2ba72dc0 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -27,6 +27,7 @@
#ifndef _LIBCPP_HAS_NO_THREADS
#include <atomic>
#endif
+#include <bit>
#include <bitset>
#include <cassert>
#include <ccomplex>
@@ -144,7 +145,6 @@
#include <experimental/coroutine>
#endif
#include <experimental/deque>
-#include <experimental/dynarray>
#include <experimental/filesystem>
#include <experimental/forward_list>
#include <experimental/functional>
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
deleted file mode 100644
index c6a83cc61bdc..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// dynarray.cons
-
-// template <class Alloc>
-// dynarray(size_type c, const Alloc& alloc);
-// template <class Alloc>
-// dynarray(size_type c, const T& v, const Alloc& alloc);
-// template <class Alloc>
-// dynarray(const dynarray& d, const Alloc& alloc);
-// template <class Alloc>
-// dynarray(initializer_list<T>, const Alloc& alloc);
-
-// ~dynarray();
-
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-#include "test_allocator.h"
-
-using std::experimental::dynarray;
-
-template <class T, class Allocator>
-void check_allocator ( const dynarray<T> &dyn, const Allocator &alloc ) {
- for ( int i = 0; i < dyn.size (); ++i )
- assert ( dyn[i].get_allocator() == alloc );
-}
-
-template <class T, class Allocator>
-void test ( const std::initializer_list<T> &vals, const Allocator &alloc ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( vals, alloc );
- assert ( d1.size () == vals.size() );
- assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
- check_allocator ( d1, alloc );
- }
-
-
-template <class T, class Allocator>
-void test ( const T &val, const Allocator &alloc1, const Allocator &alloc2 ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( 4, alloc1 );
- assert ( d1.size () == 4 );
- assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
- check_allocator ( d1, alloc1 );
-
- dynA d2 ( 7, val, alloc1 );
- assert ( d2.size () == 7 );
- assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
- check_allocator ( d2, alloc1 );
-
- dynA d3 ( d2, alloc2 );
- assert ( d3.size () == 7 );
- assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));
- check_allocator ( d3, alloc2 );
- }
-
-int main()
-{
-// This test is waiting on the resolution of LWG issue #2235
-// typedef test_allocator<char> Alloc;
-// typedef std::basic_string<char, std::char_traits<char>, Alloc> nstr;
-//
-// test ( nstr("fourteen"), Alloc(3), Alloc(4) );
-// test ( { nstr("1"), nstr("1"), nstr("2"), nstr("3"), nstr("5"), nstr("8")}, Alloc(6));
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
deleted file mode 100644
index db7484d468da..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability=macosx10.12
-// XFAIL: availability=macosx10.11
-// XFAIL: availability=macosx10.10
-// XFAIL: availability=macosx10.9
-// XFAIL: availability=macosx10.8
-// XFAIL: availability=macosx10.7
-
-// dynarray.cons
-
-// explicit dynarray(size_type c);
-// dynarray(size_type c, const T& v);
-// dynarray(initializer_list<T>);
-// dynarray(const dynarray& d);
-
-// ~dynarray();
-
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <limits>
-#include <new>
-#include <string>
-
-#include "test_macros.h"
-
-
-using std::experimental::dynarray;
-
-template <class T>
-void testInitList( const std::initializer_list<T> &vals ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( vals );
- assert ( d1.size () == vals.size() );
- assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
- }
-
-
-template <class T>
-void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( 4 );
- assert ( d1.size () == 4 );
- if (!DefaultValueIsIndeterminate) {
- assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
- }
-
- dynA d2 ( 7, val );
- assert ( d2.size () == 7 );
- assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
-
- dynA d3 ( d2 );
- assert ( d3.size () == 7 );
- assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));
- }
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
-void test_bad_length () {
- try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
- catch ( std::bad_array_length & ) { return ; }
- catch (...) { assert(false); }
- assert ( false );
-}
-#endif
-
-
-int main()
-{
- test<int> ( 14, /* DefaultValueIsIndeterminate */ true ); // ints don't get default initialized
- test<long> ( 0, true);
- test<double> ( 14.0, true );
- test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
- test<std::string> ( "fourteen" );
-
- testInitList( { 1, 1, 2, 3, 5, 8 } );
- testInitList( { 1., 1., 2., 3., 5., 8. } );
- testInitList( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
- std::string("5"), std::string("8")} );
-
-// Make sure we don't pick up the Allocator version here
- dynarray<long> d1 ( 20, 3 );
- assert ( d1.size() == 20 );
- assert ( std::all_of ( d1.begin (), d1.end (), []( long item ){ return item == 3L; } ));
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
- test_bad_length ();
-#endif
-}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
deleted file mode 100644
index 4009841355f9..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: libcpp-no-exceptions
-// XFAIL: availability
-// dynarray.cons
-
-// explicit dynarray(size_type c);
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-// The sanitizers replace new/delete with versions that do not throw bad_alloc.
-// UNSUPPORTED: sanitizer-new-delete
-
-
-#include <experimental/dynarray>
-#include <limits>
-#include <new>
-#include <cassert>
-
-
-using std::experimental::dynarray;
-
-int main() {
- try { dynarray<int>((std::numeric_limits<size_t>::max() / sizeof(int)) - 1); }
- catch (std::bad_alloc &) { return 0; }
- catch (...) { assert(false); }
- assert(false);
-}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
deleted file mode 100644
index 5c745e0d1eaf..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-
-// dynarray.data
-
-// T* data() noexcept;
-// const T* data() const noexcept;
-
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_test_const(const dynarray<T> &dyn, bool CheckEquals = true) {
- const T *data = dyn.data ();
- assert ( data != NULL );
- if (CheckEquals) {
- assert ( std::equal ( dyn.begin(), dyn.end(), data ));
- }
-}
-
-template <class T>
-void dyn_test( dynarray<T> &dyn, bool CheckEquals = true) {
- T *data = dyn.data ();
- assert ( data != NULL );
- if (CheckEquals) {
- assert ( std::equal ( dyn.begin(), dyn.end(), data ));
- }
-}
-
-
-
-template <class T>
-void test(const T &val, bool DefaultValueIsIndeterminate = false) {
- typedef dynarray<T> dynA;
-
- const bool CheckDefaultValues = !DefaultValueIsIndeterminate;
-
- dynA d1(4);
- dyn_test(d1, CheckDefaultValues);
- dyn_test_const(d1, CheckDefaultValues);
-
- dynA d2 (7, val);
- dyn_test ( d2 );
- dyn_test_const ( d2 );
-}
-
-int main()
-{
- test<int>(14, /* DefaultValueIsIndeterminate */ true);
- test<double>(14.0, true);
- test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
- test<std::string> ( "fourteen" );
-}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
deleted file mode 100644
index 1ed51538f6fa..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-
-// dynarray.data
-
-// void fill(const T& v);
-// const T* data() const noexcept;
-
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void test ( const T &val ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( 4 );
- d1.fill ( val );
- assert ( std::all_of ( d1.begin (), d1.end (),
- [&val]( const T &item ){ return item == val; } ));
- }
-
-int main()
-{
- test<int> ( 14 );
- test<double> ( 14.0 );
- test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
- test<std::string> ( "fourteen" );
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
deleted file mode 100644
index 473313f39fc4..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// UNSUPPORTED: libcpp-no-exceptions
-// XFAIL: availability
-
-// dynarray.overview
-
-// const_reference at(size_type n) const;
-// reference at(size_type n);
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_at_fail ( dynarray<T> &dyn, size_t sz ) {
- try { dyn.at (sz); }
- catch (const std::out_of_range &) { return; }
- assert ( false );
- }
-
-template <class T>
-void dyn_at_fail_const ( const dynarray<T> &dyn, size_t sz ) {
- try { dyn.at (sz); }
- catch (const std::out_of_range &) { return; }
- assert ( false );
- }
-
-
-template <class T>
-void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
- const T *data = dyn.data ();
- auto it = vals.begin ();
- for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
- assert ( data + i == &dyn.at(i));
- assert ( *it == dyn.at(i));
- }
-
- dyn_at_fail_const ( dyn, dyn.size ());
- dyn_at_fail_const ( dyn, 2*dyn.size ());
- dyn_at_fail_const ( dyn, size_t (-1));
- }
-
-template <class T>
-void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
- T *data = dyn.data ();
- auto it = vals.begin ();
- for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
- assert ( data + i == &dyn.at(i));
- assert ( *it == dyn.at(i));
- }
-
- dyn_at_fail ( dyn, dyn.size ());
- dyn_at_fail ( dyn, 2*dyn.size ());
- dyn_at_fail ( dyn, size_t (-1));
- }
-
-
-template <class T>
-void test ( std::initializer_list<T> vals ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( vals );
- dyn_test ( d1, vals );
- dyn_test_const ( d1, vals );
- }
-
-int main()
-{
- test ( { 1, 1, 2, 3, 5, 8 } );
- test ( { 1., 1., 2., 3., 5., 8. } );
- test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
- std::string("5"), std::string("8")} );
-
- test<int> ( {} );
- test<std::complex<double>> ( {} );
- test<std::string> ( {} );
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
deleted file mode 100644
index f0aa1e3ff691..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-
-// dynarray.overview
-
-
-// iterator begin() noexcept;
-// const_iterator begin() const noexcept;
-// const_iterator cbegin() const noexcept;
-// iterator end() noexcept;
-// const_iterator end() const noexcept;
-// const_iterator cend() const noexcept;
-//
-// reverse_iterator rbegin() noexcept;
-// const_reverse_iterator rbegin() const noexcept;
-// const_reverse_iterator crbegin() const noexcept;
-// reverse_iterator rend() noexcept;
-// const_reverse_iterator rend() const noexcept;
-// const_reverse_iterator crend() const noexcept;
-
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cstddef>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_test_const ( const dynarray<T> &dyn ) {
- const T *data = dyn.data ();
- assert ( data == &*dyn.begin ());
- assert ( data == &*dyn.cbegin ());
-
- assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
- assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
-
- std::ptrdiff_t ds = static_cast<std::ptrdiff_t>(dyn.size());
- assert (ds == std::distance ( dyn.begin(), dyn.end()));
- assert (ds == std::distance ( dyn.cbegin(), dyn.cend()));
- assert (ds == std::distance ( dyn.rbegin(), dyn.rend()));
- assert (ds == std::distance ( dyn.crbegin(), dyn.crend()));
-
- assert ( dyn.begin () == dyn.cbegin ());
- assert ( &*dyn.begin () == &*dyn.cbegin ());
- assert ( dyn.rbegin () == dyn.crbegin ());
- assert ( &*dyn.rbegin () == &*dyn.crbegin ());
- assert ( dyn.end () == dyn.cend ());
- assert ( dyn.rend () == dyn.crend ());
- }
-
-template <class T>
-void dyn_test ( dynarray<T> &dyn ) {
- T *data = dyn.data ();
- assert ( data == &*dyn.begin ());
- assert ( data == &*dyn.cbegin ());
-
- assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
- assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
-
- std::ptrdiff_t ds = static_cast<std::ptrdiff_t>(dyn.size());
- assert (ds == std::distance ( dyn.begin(), dyn.end()));
- assert (ds == std::distance ( dyn.cbegin(), dyn.cend()));
- assert (ds == std::distance ( dyn.rbegin(), dyn.rend()));
- assert (ds == std::distance ( dyn.crbegin(), dyn.crend()));
-
- assert ( dyn.begin () == dyn.cbegin ());
- assert ( &*dyn.begin () == &*dyn.cbegin ());
- assert ( dyn.rbegin () == dyn.crbegin ());
- assert ( &*dyn.rbegin () == &*dyn.crbegin ());
- assert ( dyn.end () == dyn.cend ());
- assert ( dyn.rend () == dyn.crend ());
- }
-
-
-template <class T>
-void test ( const T &val ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( 4 );
- dyn_test ( d1 );
- dyn_test_const ( d1 );
-
- dynA d2 ( 7, val );
- dyn_test ( d2 );
- dyn_test_const ( d2 );
- }
-
-int main()
-{
- test<int> ( 14 );
- test<double> ( 14.0 );
- test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
- test<std::string> ( "fourteen" );
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
deleted file mode 100644
index a5484296fa21..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-
-// dynarray.overview
-
-// size_type size() const noexcept;
-// size_type max_size() const noexcept;
-// bool empty() const noexcept;
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_test ( const dynarray<T> &dyn, size_t sz ) {
- assert ( dyn.size () == sz );
- assert ( dyn.max_size () == sz );
- assert ( dyn.empty () == ( sz == 0 ));
- }
-
-template <class T>
-void test ( std::initializer_list<T> vals ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( vals );
- dyn_test ( d1, vals.size ());
- }
-
-int main()
-{
- test ( { 1, 1, 2, 3, 5, 8 } );
- test ( { 1., 1., 2., 3., 5., 8. } );
- test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
- std::string("5"), std::string("8")} );
-
- test<int> ( {} );
- test<std::complex<double>> ( {} );
- test<std::string> ( {} );
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
deleted file mode 100644
index 0ba27cf925f7..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-
-// dynarray.overview
-
-// reference front();
-// const_reference front() const;
-// reference back();
-// const_reference back() const;
-
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_test_const ( const dynarray<T> &dyn, bool CheckValues = true ) {
- const T *data = dyn.data ();
- assert(data == &dyn.front());
- assert((data + dyn.size() - 1) == &dyn.back());
- if (CheckValues) {
- assert ( *data == dyn.front ());
- assert ( *(data + dyn.size() - 1 ) == dyn.back ());
- }
-}
-
-template <class T>
-void dyn_test ( dynarray<T> &dyn, bool CheckValues = true ) {
- T *data = dyn.data ();
- assert(data == &dyn.front());
- assert((data + dyn.size() - 1) == &dyn.back());
- if (CheckValues) {
- assert ( *data == dyn.front ());
- assert ( *(data + dyn.size() - 1 ) == dyn.back ());
- }
-}
-
-
-template <class T>
-void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
- typedef dynarray<T> dynA;
-
- const bool CheckDefaultValues = ! DefaultValueIsIndeterminate;
-
- dynA d1 ( 4 );
- dyn_test ( d1, CheckDefaultValues );
- dyn_test_const ( d1, CheckDefaultValues );
-
- dynA d2 ( 7, val );
- dyn_test ( d2 );
- dyn_test_const ( d2 );
-}
-
-int main()
-{
- test<int> ( 14, /* DefaultValueIsIndeterminate */ true);
- test<double> ( 14.0, true );
- test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
- test<std::string> ( "fourteen" );
-}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
deleted file mode 100644
index 4306d1e9c1b6..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-// XFAIL: availability=macosx10.12
-// XFAIL: availability=macosx10.11
-// XFAIL: availability=macosx10.10
-// XFAIL: availability=macosx10.9
-// XFAIL: availability=macosx10.8
-// XFAIL: availability=macosx10.7
-
-// dynarray.overview
-
-// const_reference at(size_type n) const;
-// reference at(size_type n);
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
- const T *data = dyn.data ();
- auto it = vals.begin ();
- for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
- assert ( data + i == &dyn[i]);
- assert ( *it == dyn[i]);
- }
- }
-
-template <class T>
-void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
- T *data = dyn.data ();
- auto it = vals.begin ();
- for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
- assert ( data + i == &dyn[i]);
- assert ( *it == dyn[i]);
- }
- }
-
-
-template <class T>
-void test ( std::initializer_list<T> vals ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( vals );
- dyn_test ( d1, vals );
- dyn_test_const ( d1, vals );
- }
-
-int main()
-{
- test ( { 1, 1, 2, 3, 5, 8 } );
- test ( { 1., 1., 2., 3., 5., 8. } );
- test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
- std::string("5"), std::string("8")} );
-
- test<int> ( {} );
- test<std::complex<double>> ( {} );
- test<std::string> ( {} );
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
deleted file mode 100644
index ab4960035060..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
-// dynarray.zero
-
-// dynarray shall provide support for the special case of construction with a size of zero.
-// In the case that the size is zero, begin() == end() == unique value.
-// The return value of data() is unspecified.
-// The effect of calling front() or back() for a zero-sized dynarray is undefined.
-
-
-
-#include <__config>
-
-#include <experimental/dynarray>
-#include <cassert>
-
-#include <algorithm>
-#include <complex>
-#include <string>
-
-using std::experimental::dynarray;
-
-template <class T>
-void test ( ) {
- typedef dynarray<T> dynA;
-
- dynA d1 ( 0 );
- assert ( d1.size() == 0 );
- assert ( d1.begin() == d1.end ());
- }
-
-int main()
-{
- test<int> ();
- test<double> ();
- test<std::complex<double>> ();
- test<std::string> ();
-}
-
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/lit.local.cfg b/test/libcxx/experimental/containers/sequences/dynarray/lit.local.cfg
deleted file mode 100644
index 93553b5130e3..000000000000
--- a/test/libcxx/experimental/containers/sequences/dynarray/lit.local.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-if ('availability' in config.available_features
- and not 'libcpp-no-exceptions' in config.available_features):
- config.unsupported = True
diff --git a/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp b/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..074a9c58c614
--- /dev/null
+++ b/test/libcxx/experimental/diagnostics/syserr/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/system_error>
+
+#include <experimental/system_error>
+
+// expected-error@experimental/system_error:* {{"<experimental/system_error> has been removed. Use <system_error> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp b/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp
new file mode 100644
index 000000000000..c4fb9593a9ee
--- /dev/null
+++ b/test/libcxx/experimental/diagnostics/syserr/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/system_error>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/system_error>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
index 40bacbcbad59..b2150fcd2716 100644
--- a/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp
@@ -106,14 +106,10 @@ struct CountCopiesAllocV2 {
int main()
{
- using PMR = ex::memory_resource*;
- using PMA = ex::polymorphic_allocator<char>;
-
{
using T = CountCopies;
using U = CountCopiesAllocV1;
using P = std::pair<T, U>;
- using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
@@ -129,7 +125,6 @@ int main()
using T = CountCopiesAllocV1;
using U = CountCopiesAllocV2;
using P = std::pair<T, U>;
- using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
@@ -146,7 +141,6 @@ int main()
using T = CountCopiesAllocV2;
using U = CountCopiesAllocV1;
using P = std::pair<T, U>;
- using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
@@ -163,7 +157,6 @@ int main()
using T = CountCopiesAllocV2;
using U = CountCopies;
using P = std::pair<T, U>;
- using TH = TestHarness<P>;
std::tuple<T> t1;
std::tuple<U> t2;
diff --git a/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp b/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp
index ccb9b710e5dc..ffcedf0bf531 100644
--- a/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp
+++ b/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp
@@ -30,7 +30,7 @@ namespace ex = std::experimental::pmr;
int main()
{
using Alloc = NullAllocator<char>;
- using R = ex::resource_adaptor<Alloc>;
+
AllocController P;
ex::resource_adaptor<Alloc> r(Alloc{P});
ex::memory_resource & m1 = r;
diff --git a/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp b/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..32fd0527d482
--- /dev/null
+++ b/test/libcxx/experimental/numerics/numeric.ops/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/numeric>
+
+#include <experimental/numeric>
+
+// expected-error@experimental/numeric:* {{"<experimental/numeric> has been removed. Use <numeric> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp b/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp
new file mode 100644
index 000000000000..37ac584a7cd4
--- /dev/null
+++ b/test/libcxx/experimental/numerics/numeric.ops/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/numeric>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/numeric>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp b/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..64f73742099b
--- /dev/null
+++ b/test/libcxx/experimental/strings/string.view/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/string_view>
+
+#include <experimental/string_view>
+
+// expected-error@experimental/string_view:* {{"<experimental/string_view> has been removed. Use <string_view> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/strings/string.view/version.pass.cpp b/test/libcxx/experimental/strings/string.view/version.pass.cpp
new file mode 100644
index 000000000000..417982e36696
--- /dev/null
+++ b/test/libcxx/experimental/strings/string.view/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/string_view>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/string_view>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..0bcda7056b4d
--- /dev/null
+++ b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/any>
+
+#include <experimental/any>
+
+// expected-error@experimental/any:* {{"<experimental/any> has been removed. Use <any> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/any/version.pass.cpp b/test/libcxx/experimental/utilities/any/version.pass.cpp
new file mode 100644
index 000000000000..bc37d8b4dbfa
--- /dev/null
+++ b/test/libcxx/experimental/utilities/any/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/any>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/any>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..1711d2f03742
--- /dev/null
+++ b/test/libcxx/experimental/utilities/optional/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/optional>
+
+#include <experimental/optional>
+
+// expected-error@experimental/optional:* {{"<experimental/optional> has been removed. Use <optional> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/optional/version.pass.cpp b/test/libcxx/experimental/utilities/optional/version.pass.cpp
new file mode 100644
index 000000000000..ef011bbe4506
--- /dev/null
+++ b/test/libcxx/experimental/utilities/optional/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/optional>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/optional>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..d9a01337a936
--- /dev/null
+++ b/test/libcxx/experimental/utilities/ratio/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/ratio>
+
+#include <experimental/ratio>
+
+// expected-error@experimental/ratio:* {{"<experimental/ratio> has been removed. Use <ratio> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/ratio/version.pass.cpp b/test/libcxx/experimental/utilities/ratio/version.pass.cpp
new file mode 100644
index 000000000000..8ebb347a44ba
--- /dev/null
+++ b/test/libcxx/experimental/utilities/ratio/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/ratio>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/ratio>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..9f3d679fc2ab
--- /dev/null
+++ b/test/libcxx/experimental/utilities/time/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/chrono>
+
+#include <experimental/chrono>
+
+// expected-error@experimental/chrono:* {{"<experimental/chrono> has been removed. Use <chrono> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/time/version.pass.cpp b/test/libcxx/experimental/utilities/time/version.pass.cpp
new file mode 100644
index 000000000000..5544a3f0e14b
--- /dev/null
+++ b/test/libcxx/experimental/utilities/time/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/chrono>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/chrono>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp b/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp
new file mode 100644
index 000000000000..520e9fbb42f0
--- /dev/null
+++ b/test/libcxx/experimental/utilities/tuple/use_header_warning.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
+// expected-error@experimental/tuple:* {{"<experimental/tuple> has been removed. Use <tuple> instead."}}
+
+int main() {}
diff --git a/test/libcxx/experimental/utilities/tuple/version.pass.cpp b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
new file mode 100644
index 000000000000..c7c9e572856d
--- /dev/null
+++ b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/tuple>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-W#warnings"
+#endif
+#include <experimental/tuple>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main() {}
diff --git a/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp b/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp
new file mode 100644
index 000000000000..0f8defcbd97d
--- /dev/null
+++ b/test/libcxx/input.output/file.streams/fstreams/fstream.close.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_fstream
+
+// close();
+
+// Inspired by PR#38052 - std::fstream still good after closing and updating content
+
+#include <fstream>
+#include <cassert>
+#include "platform_support.h"
+
+int main()
+{
+ std::string temp = get_temp_file_name();
+
+ std::fstream ofs(temp, std::ios::out | std::ios::trunc);
+ ofs << "Hello, World!\n";
+ assert( ofs.good());
+ ofs.close();
+ assert( ofs.good());
+ ofs << "Hello, World!\n";
+ assert(!ofs.good());
+
+ std::remove(temp.c_str());
+}
diff --git a/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp b/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp
index ddef5d00e5da..7e3130cf9fa9 100644
--- a/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp
+++ b/test/libcxx/language.support/cxa_deleted_virtual.pass.cpp
@@ -12,6 +12,7 @@
// Test exporting the symbol: "__cxa_deleted_virtual" in macosx
// But don't expect the symbol to be exported in previous versions.
//
+// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
diff --git a/test/libcxx/language.support/has_c11_features.pass.cpp b/test/libcxx/language.support/has_c11_features.pass.cpp
index cdccc00e21b4..4edec534eb98 100644
--- a/test/libcxx/language.support/has_c11_features.pass.cpp
+++ b/test/libcxx/language.support/has_c11_features.pass.cpp
@@ -14,6 +14,9 @@
// _LIBCPP_HAS_C11_FEATURES - which is defined in <__config>
// They should always be the same
+#include <__config>
+#include "test_macros.h"
+
#ifdef TEST_HAS_C11_FEATURES
# ifndef _LIBCPP_HAS_C11_FEATURES
# error "TEST_HAS_C11_FEATURES is defined, but _LIBCPP_HAS_C11_FEATURES is not"
diff --git a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
new file mode 100644
index 000000000000..f62e82d8e594
--- /dev/null
+++ b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -0,0 +1,260 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test libc++'s implementation of align_val_t, and the relevant new/delete
+// overloads in all dialects when -faligned-allocation is present.
+
+// Libc++ defers to the underlying MSVC library to provide the new/delete
+// definitions, which does not yet provide aligned allocation
+// XFAIL: LIBCXX-WINDOWS-FIXME
+
+// The dylibs shipped before macosx10.14 do not contain the aligned allocation
+// functions, so trying to force using those with -faligned-allocation results
+// in a link error.
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+// XFAIL: with_system_cxx_lib=macosx10.11
+// XFAIL: with_system_cxx_lib=macosx10.10
+// XFAIL: with_system_cxx_lib=macosx10.9
+// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
+// The test will fail on deployment targets that do not support sized deallocation.
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
+// XFAIL: sanitizer-new-delete, ubsan
+
+// GCC doesn't support the aligned-allocation flags.
+// XFAIL: gcc
+
+// RUN: %build -faligned-allocation -fsized-deallocation
+// RUN: %run
+// RUN: %build -faligned-allocation -fno-sized-deallocation -DNO_SIZE
+// RUN: %run
+// RUN: %build -fno-aligned-allocation -fsized-deallocation -DNO_ALIGN
+// RUN: %run
+// RUN: %build -fno-aligned-allocation -fno-sized-deallocation -DNO_ALIGN -DNO_SIZE
+// RUN: %run
+
+#include <new>
+#include <typeinfo>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct alloc_stats {
+ alloc_stats() { reset(); }
+
+ int aligned_sized_called;
+ int aligned_called;
+ int sized_called;
+ int plain_called;
+ int last_size;
+ int last_align;
+
+ void reset() {
+ aligned_sized_called = aligned_called = sized_called = plain_called = 0;
+ last_align = last_size = -1;
+ }
+
+ bool expect_plain() const {
+ assert(aligned_sized_called == 0);
+ assert(aligned_called == 0);
+ assert(sized_called == 0);
+ assert(last_size == -1);
+ assert(last_align == -1);
+ return plain_called == 1;
+ }
+
+ bool expect_size(int n) const {
+ assert(plain_called == 0);
+ assert(aligned_sized_called == 0);
+ assert(aligned_called == 0);
+ assert(last_size == n);
+ assert(last_align == -1);
+ return sized_called == 1;
+ }
+
+ bool expect_align(int a) const {
+ assert(plain_called == 0);
+ assert(aligned_sized_called == 0);
+ assert(sized_called == 0);
+ assert(last_size == -1);
+ assert(last_align == a);
+ return aligned_called == 1;
+ }
+
+ bool expect_size_align(int n, int a) const {
+ assert(plain_called == 0);
+ assert(sized_called == 0);
+ assert(aligned_called == 0);
+ assert(last_size == n);
+ assert(last_align == a);
+ return aligned_sized_called == 1;
+ }
+};
+alloc_stats stats;
+
+void operator delete(void* p)TEST_NOEXCEPT {
+ ::free(p);
+ stats.plain_called++;
+ stats.last_size = stats.last_align = -1;
+}
+
+#ifndef NO_SIZE
+void operator delete(void* p, size_t n)TEST_NOEXCEPT {
+ ::free(p);
+ stats.sized_called++;
+ stats.last_size = n;
+ stats.last_align = -1;
+}
+#endif
+
+#ifndef NO_ALIGN
+void operator delete(void* p, std::align_val_t a)TEST_NOEXCEPT {
+ ::free(p);
+ stats.aligned_called++;
+ stats.last_align = static_cast<int>(a);
+ stats.last_size = -1;
+}
+
+void operator delete(void* p, size_t n, std::align_val_t a)TEST_NOEXCEPT {
+ ::free(p);
+ stats.aligned_sized_called++;
+ stats.last_align = static_cast<int>(a);
+ stats.last_size = n;
+}
+#endif
+
+void test_libcpp_dealloc() {
+ void* p = nullptr;
+ size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2;
+ size_t under_align_val = TEST_ALIGNOF(int);
+ size_t with_size_val = 2;
+
+ {
+ std::__libcpp_deallocate_unsized(p, under_align_val);
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+
+#if defined(NO_SIZE) && defined(NO_ALIGN)
+ {
+ std::__libcpp_deallocate(p, with_size_val, over_align_val);
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+#elif defined(NO_SIZE)
+ {
+ std::__libcpp_deallocate(p, with_size_val, over_align_val);
+ assert(stats.expect_align(over_align_val));
+ }
+ stats.reset();
+#elif defined(NO_ALIGN)
+ {
+ std::__libcpp_deallocate(p, with_size_val, over_align_val);
+ assert(stats.expect_size(with_size_val));
+ }
+ stats.reset();
+#else
+ {
+ std::__libcpp_deallocate(p, with_size_val, over_align_val);
+ assert(stats.expect_size_align(with_size_val, over_align_val));
+ }
+ stats.reset();
+ {
+ std::__libcpp_deallocate_unsized(p, over_align_val);
+ assert(stats.expect_align(over_align_val));
+ }
+ stats.reset();
+ {
+ std::__libcpp_deallocate(p, with_size_val, under_align_val);
+ assert(stats.expect_size(with_size_val));
+ }
+ stats.reset();
+#endif
+}
+
+struct TEST_ALIGNAS(128) AlignedType {
+ AlignedType() : elem(0) {}
+ TEST_ALIGNAS(128) char elem;
+};
+
+void test_allocator_and_new_match() {
+ stats.reset();
+#if defined(NO_SIZE) && defined(NO_ALIGN)
+ {
+ int* x = new int(42);
+ delete x;
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+ {
+ AlignedType* a = new AlignedType();
+ delete a;
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+#elif defined(NO_SIZE)
+ stats.reset();
+#if TEST_STD_VER >= 11
+ {
+ int* x = new int(42);
+ delete x;
+ assert(stats.expect_plain());
+ }
+#endif
+ stats.reset();
+ {
+ AlignedType* a = new AlignedType();
+ delete a;
+ assert(stats.expect_align(TEST_ALIGNOF(AlignedType)));
+ }
+ stats.reset();
+#elif defined(NO_ALIGN)
+ stats.reset();
+ {
+ int* x = new int(42);
+ delete x;
+ assert(stats.expect_size(sizeof(int)));
+ }
+ stats.reset();
+ {
+ AlignedType* a = new AlignedType();
+ delete a;
+ assert(stats.expect_size(sizeof(AlignedType)));
+ }
+ stats.reset();
+#else
+ stats.reset();
+ {
+ int* x = new int(42);
+ delete x;
+ assert(stats.expect_size(sizeof(int)));
+ }
+ stats.reset();
+ {
+ AlignedType* a = new AlignedType();
+ delete a;
+ assert(stats.expect_size_align(sizeof(AlignedType),
+ TEST_ALIGNOF(AlignedType)));
+ }
+ stats.reset();
+#endif
+}
+
+int main() {
+ test_libcpp_dealloc();
+ test_allocator_and_new_match();
+}
diff --git a/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp b/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
index 388fbebbd7b0..d7b4cca63aa1 100644
--- a/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
+++ b/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// test libc++'s implementation of align_val_t, and the relevent new/delete
+// test libc++'s implementation of align_val_t, and the relevant new/delete
// overloads in all dialects when -faligned-allocation is present.
// Libc++ defers to the underlying MSVC library to provide the new/delete
@@ -16,12 +16,16 @@
// REQUIRES: -faligned-allocation
+// The dylibs shipped before macosx10.14 do not contain the aligned allocation
+// functions, so trying to force using those with -faligned-allocation results
+// in a link error.
+// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
// RUN: %build -faligned-allocation
// RUN: %run
diff --git a/test/libcxx/libcpp_alignof.pass.cpp b/test/libcxx/libcpp_alignof.pass.cpp
new file mode 100644
index 000000000000..ba0df807e82d
--- /dev/null
+++ b/test/libcxx/libcpp_alignof.pass.cpp
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that _LIBCPP_ALIGNOF acts the same as the C++11 keyword `alignof`, and
+// not as the GNU extension `__alignof`. The former returns the minimal required
+// alignment for a type, whereas the latter returns the preferred alignment.
+//
+// See llvm.org/PR39713
+
+#include <type_traits>
+#include "test_macros.h"
+
+template <class T>
+void test() {
+ static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of<T>::value, "");
+ static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), "");
+#if TEST_STD_VER >= 11
+ static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), "");
+#endif
+#ifdef TEST_COMPILER_CLANG
+ static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), "");
+#endif
+}
+
+int main() {
+ test<int>();
+ test<long long>();
+ test<double>();
+ test<long double>();
+}
diff --git a/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp
index c37d23433148..368076dee3ad 100644
--- a/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp
+++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp
@@ -7,31 +7,25 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11
-// XFAIL: availability
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// AppleClang <= 10 enables aligned allocation regardless of the deployment
+// target, so this test would fail.
+// UNSUPPORTED: apple-clang-9, apple-clang-10
+
+// XFAIL: availability=macosx10.13
// XFAIL: availability=macosx10.12
// XFAIL: availability=macosx10.11
// XFAIL: availability=macosx10.10
// XFAIL: availability=macosx10.9
-// XFAIL: availability=macosx10.7
// XFAIL: availability=macosx10.8
-
-// test bad_array_length
+// XFAIL: availability=macosx10.7
#include <new>
-#include <type_traits>
-#include <cassert>
-int main()
-{
- static_assert((std::is_base_of<std::bad_alloc, std::bad_array_length>::value),
- "std::is_base_of<std::bad_alloc, std::bad_array_length>::value");
- static_assert(std::is_polymorphic<std::bad_array_length>::value,
- "std::is_polymorphic<std::bad_array_length>::value");
- std::bad_array_length b;
- std::bad_array_length b2 = b;
- b2 = b;
- const char* w = b2.what();
- assert(w);
-}
+
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+# error "libc++ should have aligned allocation in C++17 and up when targeting a platform that supports it"
+#endif
+
+int main() { }
diff --git a/test/libcxx/min_max_macros.sh.cpp b/test/libcxx/min_max_macros.sh.cpp
index 087aa3645a50..7b9202d952fb 100644
--- a/test/libcxx/min_max_macros.sh.cpp
+++ b/test/libcxx/min_max_macros.sh.cpp
@@ -46,6 +46,8 @@ TEST_MACROS();
TEST_MACROS();
#include <cfloat>
TEST_MACROS();
+#include <charconv>
+TEST_MACROS();
#include <chrono>
TEST_MACROS();
#include <cinttypes>
@@ -239,8 +241,6 @@ TEST_MACROS();
TEST_MACROS();
#include <experimental/deque>
TEST_MACROS();
-#include <experimental/dynarray>
-TEST_MACROS();
#include <experimental/filesystem>
TEST_MACROS();
#include <experimental/forward_list>
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp
index 6c2929d7f1d3..09a6aa8a6343 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db1.pass.cpp
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <exception>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -30,7 +31,7 @@ int main()
l1.erase(i);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp
index d20fcd4623b7..1ff02932bd98 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_db2.pass.cpp
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <exception>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -31,7 +32,7 @@ int main()
l1.erase(i);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp
index 5015241ad63e..46fa5bf434dd 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db1.pass.cpp
@@ -20,6 +20,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -30,7 +31,7 @@ int main()
std::string::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp
index 6a23bf88ca5c..3ccbfad70a6b 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db2.pass.cpp
@@ -20,6 +20,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -30,7 +31,7 @@ int main()
std::string::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp
index a8443818aea5..e493dfea9e05 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db3.pass.cpp
@@ -20,6 +20,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -30,7 +31,7 @@ int main()
std::string::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp
index 0549e816b44c..918cffe733fd 100644
--- a/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp
+++ b/test/libcxx/strings/basic.string/string.modifiers/erase_iter_iter_db4.pass.cpp
@@ -20,6 +20,7 @@
#include <exception>
#include <cstdlib>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -29,7 +30,7 @@ int main()
std::string::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
assert(false);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S l1("123");
diff --git a/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp
new file mode 100644
index 000000000000..a3fa585e44ff
--- /dev/null
+++ b/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// __resize_default_init(size_type)
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+void write_c_str(char *buf, int size) {
+ for (int i=0; i < size; ++i) {
+ buf[i] = 'a';
+ }
+ buf[size] = '\0';
+}
+
+void test_buffer_usage()
+{
+ {
+ unsigned buff_size = 125;
+ unsigned used_size = buff_size - 16;
+ std::string s;
+ s.__resize_default_init(buff_size);
+ write_c_str(&s[0], used_size);
+ assert(s.size() == buff_size);
+ assert(strlen(s.data()) == used_size);
+ s.__resize_default_init(used_size);
+ assert(s.size() == used_size);
+ assert(s.data()[used_size] == '\0');
+ for (unsigned i=0; i < used_size; ++i) {
+ assert(s[i] == 'a');
+ }
+ }
+}
+
+void test_basic() {
+ {
+ std::string s;
+ s.__resize_default_init(3);
+ assert(s.size() == 3);
+ assert(s.data()[3] == '\0');
+ for (int i=0; i < 3; ++i)
+ s[i] = 'a' + i;
+ s.__resize_default_init(1);
+ assert(s[0] == 'a');
+ assert(s.data()[1] == '\0');
+ assert(s.size() == 1);
+ }
+}
+
+int main() {
+ test_basic();
+ test_buffer_usage();
+}
diff --git a/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp b/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
index 6024d9978433..74a4657196e4 100644
--- a/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
+++ b/test/libcxx/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
@@ -21,10 +21,20 @@
#include <mutex>
+#include "test_macros.h"
+
std::mutex m;
int foo __attribute__((guarded_by(m)));
+static void scoped() {
+#if TEST_STD_VER >= 17
+ std::scoped_lock<std::mutex> lock(m);
+ foo++;
+#endif
+}
+
int main() {
+ scoped();
std::lock_guard<std::mutex> lock(m);
foo++;
}
diff --git a/test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
index b46c2cdec6cb..3c0571bf9c22 100644
--- a/test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
+++ b/test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
@@ -57,7 +57,6 @@ int main()
typedef std::chrono::system_clock Clock;
typedef Clock::time_point time_point;
- typedef Clock::duration duration;
std::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
std::this_thread::sleep_for(ms);
diff --git a/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp b/test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp
index 0b9b6e717c3a..cdfb027364be 100644
--- a/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp
+++ b/test/libcxx/utilities/optional/optional.object/triviality.abi.pass.cpp
@@ -8,8 +8,18 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
+
// <optional>
+// This test asserts the triviality of special member functions of optional<T>
+// whenever T has these special member functions trivial. The goal of this test
+// is to make sure that we do not change the triviality of those, since that
+// constitues an ABI break (small enough optionals would be passed by registers).
+//
+// constexpr optional(const optional& rhs);
+// constexpr optional(optional&& rhs) noexcept(see below);
+// constexpr optional<T>& operator=(const optional& rhs);
+// constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
#include <optional>
#include <type_traits>
@@ -21,41 +31,27 @@ template <class T>
struct SpecialMemberTest {
using O = std::optional<T>;
- static_assert(std::is_default_constructible_v<O>,
- "optional is always default constructible.");
- static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
- "optional<T> is copy constructible if and only if T is copy constructible.");
- static_assert(std::is_move_constructible_v<O> ==
- (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
- "optional<T> is move constructible if and only if T is copy or move constructible.");
- static_assert(std::is_copy_assignable_v<O> ==
- (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
- "optional<T> is copy assignable if and only if T is both copy "
- "constructible and copy assignable.");
- static_assert(std::is_move_assignable_v<O> ==
- ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) ||
- (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)),
- "optional<T> is move assignable if and only if T is both move constructible and "
- "move assignable, or both copy constructible and copy assignable.");
-
- // The following tests are for not-yet-standardized behavior (P0602):
static_assert(std::is_trivially_destructible_v<O> ==
std::is_trivially_destructible_v<T>,
"optional<T> is trivially destructible if and only if T is.");
+
static_assert(std::is_trivially_copy_constructible_v<O> ==
std::is_trivially_copy_constructible_v<T>,
"optional<T> is trivially copy constructible if and only if T is.");
+
static_assert(std::is_trivially_move_constructible_v<O> ==
std::is_trivially_move_constructible_v<T> ||
(!std::is_move_constructible_v<T> && std::is_trivially_copy_constructible_v<T>),
"optional<T> is trivially move constructible if T is trivially move constructible, "
"or if T is trivially copy constructible and is not move constructible.");
+
static_assert(std::is_trivially_copy_assignable_v<O> ==
(std::is_trivially_destructible_v<T> &&
std::is_trivially_copy_constructible_v<T> &&
std::is_trivially_copy_assignable_v<T>),
"optional<T> is trivially copy assignable if and only if T is trivially destructible, "
"trivially copy constructible, and trivially copy assignable.");
+
static_assert(std::is_trivially_move_assignable_v<O> ==
(std::is_trivially_destructible_v<T> &&
((std::is_trivially_move_constructible_v<T> && std::is_trivially_move_assignable_v<T>) ||
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
new file mode 100644
index 000000000000..6a3e613e9dcb
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template<class U, class V> pair(U&& x, V&& y);
+
+#include <utility>
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main() {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, int, int>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, int, int>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, int, int>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, int, int>::value, "");
+ }
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
new file mode 100644
index 000000000000..6a2401223755
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// pair(const T1& x, const T2& y);
+
+#include <utility>
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {}
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(ImplicitNothrowT const&) noexcept {}
+};
+
+int main() {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ ExplicitT const&, ExplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ ExplicitNothrowT const&, ExplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ ExplicitT const&, ExplicitNothrowT const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ ExplicitNothrowT const&, ExplicitNothrowT const&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ ImplicitT const&, ImplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ ImplicitNothrowT const&, ImplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ ImplicitT const&, ImplicitNothrowT const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ ImplicitNothrowT const&, ImplicitNothrowT const&>::value, "");
+ }
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
new file mode 100644
index 000000000000..edb3bbf64afb
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class U, class V> EXPLICIT constexpr pair(const pair<U, V>& p);
+
+#include <utility>
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main() {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ }
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp
new file mode 100644
index 000000000000..2dbf5511dd16
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/default.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// constexpr pair();
+
+#include <utility>
+#include <type_traits>
+
+
+struct ThrowingDefault {
+ ThrowingDefault() { }
+};
+
+struct NonThrowingDefault {
+ NonThrowingDefault() noexcept { }
+};
+
+int main() {
+
+ static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, ThrowingDefault>>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, ThrowingDefault>>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, NonThrowingDefault>>::value, "");
+ static_assert( std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, NonThrowingDefault>>::value, "");
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp
index 8b5969d5198c..58ea6ecde992 100644
--- a/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp
@@ -30,6 +30,7 @@
#include <utility>
#include <type_traits>
#include <cstdlib>
+#include <cstddef>
#include <cassert>
#include "test_macros.h"
@@ -86,7 +87,7 @@ static_assert(!HasNonTrivialABI<Trivial>::value, "");
#endif
-int main()
+void test_trivial()
{
{
typedef std::pair<int, short> P;
@@ -150,3 +151,15 @@ int main()
}
#endif
}
+
+void test_layout() {
+ typedef std::pair<std::pair<char, char>, char> PairT;
+ static_assert(sizeof(PairT) == 3, "");
+ static_assert(TEST_ALIGNOF(PairT) == TEST_ALIGNOF(char), "");
+ static_assert(offsetof(PairT, first) == 0, "");
+}
+
+int main() {
+ test_trivial();
+ test_layout();
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp
index 2a92240a63d2..8bfeeea5d2a6 100644
--- a/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp
@@ -20,6 +20,6 @@ int main()
{
typedef std::pair<int, double> P;
std::tuple_element<2, P>::type foo; // expected-note {{requested here}}
- // expected-error@utility:* {{static_assert failed "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"}}
+ // expected-error-re@utility:* {{static_assert failed{{( due to requirement '2U[L]{0,2} < 2')?}} "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"}}
}
}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
new file mode 100644
index 000000000000..81dad3bc2ffa
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class... Args1, class... Args2>
+// pair(piecewise_construct_t, tuple<Args1...> first_args,
+// tuple<Args2...> second_args);
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "archetypes.hpp"
+
+
+int main() {
+ using NonThrowingConvert = NonThrowingTypes::ConvertingType;
+ using ThrowingConvert = NonTrivialTypes::ConvertingType;
+ static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, ThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<NonThrowingConvert, ThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, NonThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<NonThrowingConvert, NonThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
new file mode 100644
index 000000000000..5d8d36262f17
--- /dev/null
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class U, class V> pair(pair<U, V>&& p);
+
+#include <type_traits>
+#include <utility>
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main() {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ }
+}
diff --git a/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp
index ec9cc7ec3e02..734623388779 100644
--- a/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp
+++ b/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp
@@ -25,6 +25,7 @@
#include <utility>
#include <type_traits>
#include <cstdlib>
+#include <cstddef>
#include <cassert>
#include "test_macros.h"
@@ -81,7 +82,7 @@ static_assert(HasTrivialABI<Trivial>::value, "");
#endif
-int main()
+void test_trivial()
{
{
typedef std::pair<int, short> P;
@@ -145,3 +146,15 @@ int main()
}
#endif
}
+
+void test_layout() {
+ typedef std::pair<std::pair<char, char>, char> PairT;
+ static_assert(sizeof(PairT) == 3, "");
+ static_assert(TEST_ALIGNOF(PairT) == TEST_ALIGNOF(char), "");
+ static_assert(offsetof(PairT, first) == 0, "");
+}
+
+int main() {
+ test_trivial();
+ test_layout();
+}
diff --git a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp
index f39a445b98af..c4522682c4b8 100644
--- a/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp
+++ b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp
@@ -31,6 +31,6 @@ int main()
{
typedef std::variant<int, double> T;
std::variant_alternative<2, T>::type foo; // expected-note {{requested here}}
- // expected-error@variant:* {{static_assert failed "Index out of bounds in std::variant_alternative<>"}}
+ // expected-error-re@variant:* {{static_assert failed{{( due to requirement '2U[L]{0,2} < sizeof...\(_Types\)')?}} "Index out of bounds in std::variant_alternative<>"}}
}
}
diff --git a/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp
index a836ef5169ef..c309aaaaea18 100644
--- a/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp
+++ b/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp
@@ -24,7 +24,8 @@ struct make_variant_imp;
template <size_t ...Indices>
struct make_variant_imp<std::integer_sequence<size_t, Indices...>> {
- using type = std::variant<decltype((Indices, char(0)))...>;
+ template <size_t> using AlwaysChar = char;
+ using type = std::variant<AlwaysChar<Indices>...>;
};
template <size_t N>
diff --git a/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp b/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp
index d769ad850c31..3d37d052ccc9 100644
--- a/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp
+++ b/test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.fail.cpp
@@ -34,7 +34,7 @@ template <class PopulationIterator, class SampleIterator> void test() {
}
int main() {
- // expected-error@algorithm:* {{static_assert failed "SampleIterator must meet the requirements of RandomAccessIterator"}}
+ // expected-error-re@algorithm:* {{static_assert failed{{( due to requirement '.*')?}} "SampleIterator must meet the requirements of RandomAccessIterator"}}
// expected-error@algorithm:* 2 {{does not provide a subscript operator}}
// expected-error@algorithm:* {{invalid operands}}
test<input_iterator<int *>, output_iterator<int *> >();
diff --git a/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp b/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp
index 76ac991653eb..ac3b95fbe2a7 100644
--- a/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp
+++ b/test/std/algorithms/alg.nonmodifying/alg.find.end/find_end_pred.pass.cpp
@@ -16,6 +16,7 @@
// find_end(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, Pred pred);
#include <algorithm>
+#include <functional>
#include <cassert>
#include "test_macros.h"
diff --git a/test/std/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp b/test/std/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
index 12bd938d2968..cbf87c6c2a89 100644
--- a/test/std/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
+++ b/test/std/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
@@ -44,6 +44,18 @@ constexpr bool test_constexpr() {
}
#endif
+
+struct S {
+ S(int i) : i_(i) {}
+ bool operator==(const S& other) = delete;
+ int i_;
+};
+
+struct eq {
+ bool operator()(const S& a, const S&b) { return a.i_ == b.i_; }
+};
+
+
int main()
{
{
@@ -739,14 +751,6 @@ int main()
#endif
}
{
- struct S {
- S(int i) : i_(i) {}
- bool operator==(const S& other) = delete;
- int i_;
- };
- struct eq {
- bool operator()(const S& a, const S&b) { return a.i_ == b.i_; }
- };
const S a[] = {S(0), S(1)};
const S b[] = {S(1), S(0)};
const unsigned sa = sizeof(a)/sizeof(a[0]);
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp b/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp
new file mode 100644
index 000000000000..a1069dee7aef
--- /dev/null
+++ b/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template<ForwardIterator Iter>
+// max_element(Iter first, Iter last);
+
+#include <algorithm>
+#include <cassert>
+
+#include "test_iterators.h"
+
+int main() {
+ int arr[] = {1, 2, 3};
+ const int *b = std::begin(arr), *e = std::end(arr);
+ typedef input_iterator<const int*> Iter;
+ {
+ // expected-error@algorithm:* {{"std::min_element requires a ForwardIterator"}}
+ std::min_element(Iter(b), Iter(e));
+ }
+ {
+ // expected-error@algorithm:* {{"std::max_element requires a ForwardIterator"}}
+ std::max_element(Iter(b), Iter(e));
+ }
+ {
+ // expected-error@algorithm:* {{"std::minmax_element requires a ForwardIterator"}}
+ std::minmax_element(Iter(b), Iter(e));
+ }
+
+}
diff --git a/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
index 7a8d4c1f4a69..43436e65a90a 100644
--- a/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
+++ b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
@@ -59,7 +59,7 @@ void checkLongLongTypes() {
static_assert((0 != ATOMIC_LLONG_LOCK_FREE) == ExpectLockFree, "");
}
-int main()
+void run()
{
// structs and unions can't be defined in the template invocation.
// Work around this with a typedef.
@@ -134,3 +134,5 @@ int main()
static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
}
+
+int main() { run(); }
diff --git a/test/std/containers/Emplaceable.h b/test/std/containers/Emplaceable.h
index 331a81ff311f..04b1f8543584 100644
--- a/test/std/containers/Emplaceable.h
+++ b/test/std/containers/Emplaceable.h
@@ -10,7 +10,7 @@
#ifndef EMPLACEABLE_H
#define EMPLACEABLE_H
-#include <utility>
+#include <functional>
#include "test_macros.h"
#if TEST_STD_VER >= 11
diff --git a/test/std/containers/associative/map/map.access/at.pass.cpp b/test/std/containers/associative/map/map.access/at.pass.cpp
index 5822706fbfb3..76eda046c0df 100644
--- a/test/std/containers/associative/map/map.access/at.pass.cpp
+++ b/test/std/containers/associative/map/map.access/at.pass.cpp
@@ -14,8 +14,9 @@
// mapped_type& at(const key_type& k);
// const mapped_type& at(const key_type& k) const;
-#include <map>
#include <cassert>
+#include <map>
+#include <stdexcept>
#include "min_allocator.h"
#include "test_macros.h"
diff --git a/test/std/containers/associative/map/map.access/index_key.pass.cpp b/test/std/containers/associative/map/map.access/index_key.pass.cpp
index 3b1c21fd5da4..5f3d109d1ef7 100644
--- a/test/std/containers/associative/map/map.access/index_key.pass.cpp
+++ b/test/std/containers/associative/map/map.access/index_key.pass.cpp
@@ -84,7 +84,6 @@ int main()
using Container = TCT::map<>;
using Key = Container::key_type;
using MappedType = Container::mapped_type;
- using ValueTp = Container::value_type;
ConstructController* cc = getConstructController();
cc->reset();
{
diff --git a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
index e5580bca3955..bc91475c26b7 100644
--- a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
+++ b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
@@ -61,7 +61,6 @@ int main()
using Container = TCT::map<>;
using Key = Container::key_type;
using MappedType = Container::mapped_type;
- using ValueTp = Container::value_type;
ConstructController* cc = getConstructController();
cc->reset();
{
diff --git a/test/std/containers/associative/map/map.access/max_size.pass.cpp b/test/std/containers/associative/map/map.access/max_size.pass.cpp
index 82a817a1f4ae..9df3b074e40f 100644
--- a/test/std/containers/associative/map/map.access/max_size.pass.cpp
+++ b/test/std/containers/associative/map/map.access/max_size.pass.cpp
@@ -34,18 +34,18 @@ int main()
{
typedef limited_allocator<KV, (size_t)-1> A;
typedef std::map<int, int, std::less<int>, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
- }
- {
- typedef std::map<char, int> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
- C c;
- assert(c.max_size() <= max_dist);
- assert(c.max_size() <= alloc_max_size(c.get_allocator()));
- }
+ }
+ {
+ typedef std::map<char, int> C;
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
+ C c;
+ assert(c.max_size() <= max_dist);
+ assert(c.max_size() <= alloc_max_size(c.get_allocator()));
+ }
}
diff --git a/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..f8cbc15d1645
--- /dev/null
+++ b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <map>
+
+// template <class Key, class T, class Compare, class Allocator, class Predicate>
+// void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
+
+#include <map>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret[v] = v + 10;
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == make<M>(expected));
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v.first == 1;};
+ auto is2 = [](auto v) { return v.first == 2;};
+ auto is3 = [](auto v) { return v.first == 3;};
+ auto is4 = [](auto v) { return v.first == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::map<int, int>>();
+ test<std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> ();
+ test<std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> ();
+
+ test<std::map<long, short>>();
+ test<std::map<short, double>>();
+}
+
diff --git a/test/std/containers/associative/map/map.modifiers/clear.pass.cpp b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
index 1f36a6f10cb0..ab4642fa88e6 100644
--- a/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
+++ b/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
@@ -11,11 +11,12 @@
// class map
-// void clear();
+// void clear() noexcept;
#include <map>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
@@ -56,6 +58,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
diff --git a/test/std/containers/associative/map/map.modifiers/merge.pass.cpp b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
new file mode 100644
index 000000000000..bb75e1d60293
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
@@ -0,0 +1,150 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// template <class C2>
+// void merge(map<key_type, value_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(map<key_type, value_type, C2, allocator_type>&& source);
+// template <class C2>
+// void merge(multimap<key_type, value_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
+
+#include <map>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Map>
+bool map_equal(const Map& map, Map other)
+{
+ return map == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct throw_comparator
+{
+ bool& should_throw_;
+
+ throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
+
+ template <class T>
+ bool operator()(const T& lhs, const T& rhs) const
+ {
+ if (should_throw_)
+ throw 0;
+ return lhs < rhs;
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::map<int, int> src{{1, 0}, {3, 0}, {5, 0}};
+ std::map<int, int> dst{{2, 0}, {4, 0}, {5, 0}};
+ dst.merge(src);
+ assert(map_equal(src, {{5,0}}));
+ assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::map<Counter<int>, int, throw_comparator> map_type;
+ map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw));
+ map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw))));
+ assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct comparator
+ {
+ comparator() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ {
+ typedef std::map<Counter<int>, int, std::less<Counter<int>>> first_map_type;
+ typedef std::map<Counter<int>, int, comparator> second_map_type;
+ typedef std::multimap<Counter<int>, int, comparator> third_map_type;
+
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {{2, 0}, {3, 0}}));
+ assert(map_equal(third, {{1, 0}, {3, 0}}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {{2, 0}, {3, 0}}));
+ assert(map_equal(third, {{1, 0}, {3, 0}}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ std::map<int, int> first;
+ {
+ std::map<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::multimap<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/associative/multimap/max_size.pass.cpp b/test/std/containers/associative/multimap/max_size.pass.cpp
index 8d5ec1148a22..c836a182356f 100644
--- a/test/std/containers/associative/multimap/max_size.pass.cpp
+++ b/test/std/containers/associative/multimap/max_size.pass.cpp
@@ -34,18 +34,18 @@ int main()
{
typedef limited_allocator<KV, (size_t)-1> A;
typedef std::multimap<int, int, std::less<int>, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
- }
- {
- typedef std::multimap<char, int> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
- C c;
- assert(c.max_size() <= max_dist);
- assert(c.max_size() <= alloc_max_size(c.get_allocator()));
- }
+ }
+ {
+ typedef std::multimap<char, int> C;
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
+ C c;
+ assert(c.max_size() <= max_dist);
+ assert(c.max_size() <= alloc_max_size(c.get_allocator()));
+ }
}
diff --git a/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp b/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..8e786fdc9476
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <map>
+
+// template <class Key, class T, class Compare, class Allocator, class Predicate>
+// void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
+
+#include <map>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret.insert(typename M::value_type(v, v + 10));
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == make<M>(expected));
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v.first == 1;};
+ auto is2 = [](auto v) { return v.first == 2;};
+ auto is3 = [](auto v) { return v.first == 3;};
+ auto is4 = [](auto v) { return v.first == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+ test0<S>({1,1}, is1, {});
+ test0<S>({1,1}, is3, {1,1});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,1,1}, is1, {});
+ test0<S>({1,1,1}, is2, {1,1,1});
+ test0<S>({1,1,2}, is1, {2});
+ test0<S>({1,1,2}, is2, {1,1});
+ test0<S>({1,1,2}, is3, {1,1,2});
+ test0<S>({1,2,2}, is1, {2,2});
+ test0<S>({1,2,2}, is2, {1});
+ test0<S>({1,2,2}, is3, {1,2,2});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::multimap<int, int>>();
+ test<std::multimap<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>> ();
+ test<std::multimap<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>> ();
+
+ test<std::multimap<long, short>>();
+ test<std::multimap<short, double>>();
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
index 321f4d0bd000..546a406fe1bf 100644
--- a/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
@@ -11,11 +11,12 @@
// class multimap
-// void clear();
+// void clear() noexcept;
#include <map>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
@@ -56,6 +58,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
new file mode 100644
index 000000000000..f0e38c255b8e
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
@@ -0,0 +1,150 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <map>
+
+// class multimap
+
+// template <class C2>
+// void merge(map<key_type, value_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(map<key_type, value_type, C2, allocator_type>&& source);
+// template <class C2>
+// void merge(multimap<key_type, value_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
+
+#include <map>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Map>
+bool map_equal(const Map& map, Map other)
+{
+ return map == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct throw_comparator
+{
+ bool& should_throw_;
+
+ throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
+
+ template <class T>
+ bool operator()(const T& lhs, const T& rhs) const
+ {
+ if (should_throw_)
+ throw 0;
+ return lhs < rhs;
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::multimap<int, int> src{{1, 0}, {3, 0}, {5, 0}};
+ std::multimap<int, int> dst{{2, 0}, {4, 0}, {5, 0}};
+ dst.merge(src);
+ assert(map_equal(src, {}));
+ assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {5, 0}}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::multimap<Counter<int>, int, throw_comparator> map_type;
+ map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw));
+ map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw))));
+ assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct comparator
+ {
+ comparator() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ {
+ typedef std::multimap<Counter<int>, int, std::less<Counter<int>>> first_map_type;
+ typedef std::multimap<Counter<int>, int, comparator> second_map_type;
+ typedef std::map<Counter<int>, int, comparator> third_map_type;
+
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(map_equal(first, {{1, 0}, {1, 0}, {2, 0}, {2, 0}, {3, 0}, {3, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {}));
+ assert(map_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(map_equal(first, {{1, 0}, {1, 0}, {2, 0}, {2, 0}, {3, 0}, {3, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {}));
+ assert(map_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ std::multimap<int, int> first;
+ {
+ std::multimap<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::multimap<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/associative/multiset/clear.pass.cpp b/test/std/containers/associative/multiset/clear.pass.cpp
index f762ef7d3504..59ee02ece1d2 100644
--- a/test/std/containers/associative/multiset/clear.pass.cpp
+++ b/test/std/containers/associative/multiset/clear.pass.cpp
@@ -11,11 +11,12 @@
// class multiset
-// void clear();
+// void clear() noexcept;
#include <set>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
@@ -56,6 +58,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
diff --git a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multiset/insert_emplace_allocator_requirements.pass.cpp
index a280d10d5ab2..4bd2c88f8a35 100644
--- a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/associative/multiset/insert_emplace_allocator_requirements.pass.cpp
@@ -23,4 +23,5 @@
int main()
{
testMultisetInsert<TCT::multiset<> >();
+ testMultisetEmplace<TCT::multiset<> >();
}
diff --git a/test/std/containers/associative/multiset/max_size.pass.cpp b/test/std/containers/associative/multiset/max_size.pass.cpp
index 8ca34ba82739..8c5b15e39c11 100644
--- a/test/std/containers/associative/multiset/max_size.pass.cpp
+++ b/test/std/containers/associative/multiset/max_size.pass.cpp
@@ -33,16 +33,16 @@ int main()
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::multiset<int, std::less<int>, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::multiset<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/associative/multiset/merge.pass.cpp b/test/std/containers/associative/multiset/merge.pass.cpp
new file mode 100644
index 000000000000..8ab992889e41
--- /dev/null
+++ b/test/std/containers/associative/multiset/merge.pass.cpp
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class multiset
+
+// template <class C2>
+// void merge(set<Key, C2, Allocator>& source);
+// template <class C2>
+// void merge(set<Key, C2, Allocator>&& source);
+// template <class C2>
+// void merge(multiset<Key, C2, Allocator>& source);
+// template <class C2>
+// void merge(multiset<Key, C2, Allocator>&& source);
+
+#include <set>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Set>
+bool set_equal(const Set& set, Set other)
+{
+ return set == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct throw_comparator
+{
+ bool& should_throw_;
+
+ throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
+
+ template <class T>
+ bool operator()(const T& lhs, const T& rhs) const
+ {
+ if (should_throw_)
+ throw 0;
+ return lhs < rhs;
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::multiset<int> src{1, 3, 5};
+ std::multiset<int> dst{2, 4, 5};
+ dst.merge(src);
+ assert(set_equal(src, {}));
+ assert(set_equal(dst, {1, 2, 3, 4, 5, 5}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::multiset<Counter<int>, throw_comparator> set_type;
+ set_type src({1, 3, 5}, throw_comparator(do_throw));
+ set_type dst({2, 4, 5}, throw_comparator(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(set_equal(src, set_type({1, 3, 5}, throw_comparator(do_throw))));
+ assert(set_equal(dst, set_type({2, 4, 5}, throw_comparator(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct comparator
+ {
+ comparator() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ {
+ typedef std::multiset<Counter<int>, std::less<Counter<int>>> first_set_type;
+ typedef std::multiset<Counter<int>, comparator> second_set_type;
+ typedef std::set<Counter<int>, comparator> third_set_type;
+
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4}));
+ assert(set_equal(second, {}));
+ assert(set_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4}));
+ assert(set_equal(second, {}));
+ assert(set_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::multiset<int> first;
+ {
+ std::multiset<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::set<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp b/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..3c619bb687f4
--- /dev/null
+++ b/test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <set>
+
+// template <class T, class Compare, class Allocator, class Predicate>
+// void erase_if(multiset<T, Compare, Allocator>& c, Predicate pred);
+
+#include <set>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+ test0(S({1,1}), is1, S());
+ test0(S({1,1}), is3, S({1,1}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,1,1}), is1, S());
+ test0(S({1,1,1}), is2, S({1,1,1}));
+ test0(S({1,1,2}), is1, S({2}));
+ test0(S({1,1,2}), is2, S({1,1}));
+ test0(S({1,1,2}), is3, S({1,1,2}));
+ test0(S({1,2,2}), is1, S({2,2}));
+ test0(S({1,2,2}), is2, S({1}));
+ test0(S({1,2,2}), is3, S({1,2,2}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::multiset<int>>();
+ test<std::multiset<int, std::less<int>, min_allocator<int>>> ();
+ test<std::multiset<int, std::less<int>, test_allocator<int>>> ();
+
+ test<std::multiset<long>>();
+ test<std::multiset<double>>();
+}
diff --git a/test/std/containers/associative/set/clear.pass.cpp b/test/std/containers/associative/set/clear.pass.cpp
index 7a5bf4b14a71..1be3ed2b8877 100644
--- a/test/std/containers/associative/set/clear.pass.cpp
+++ b/test/std/containers/associative/set/clear.pass.cpp
@@ -11,11 +11,12 @@
// class set
-// void clear();
+// void clear() noexcept;
#include <set>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
@@ -56,6 +58,7 @@ int main()
};
M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
assert(m.size() == 8);
+ ASSERT_NOEXCEPT(m.clear());
m.clear();
assert(m.size() == 0);
}
diff --git a/test/std/containers/associative/set/max_size.pass.cpp b/test/std/containers/associative/set/max_size.pass.cpp
index c894eb51b1ee..8be84046e1ac 100644
--- a/test/std/containers/associative/set/max_size.pass.cpp
+++ b/test/std/containers/associative/set/max_size.pass.cpp
@@ -33,16 +33,16 @@ int main()
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::set<int, std::less<int>, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::set<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/associative/set/merge.pass.cpp b/test/std/containers/associative/set/merge.pass.cpp
new file mode 100644
index 000000000000..bbae22c77ea5
--- /dev/null
+++ b/test/std/containers/associative/set/merge.pass.cpp
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <set>
+
+// class set
+
+// template <class C2>
+// void merge(set<key_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(set<key_type, C2, allocator_type>&& source);
+// template <class C2>
+// void merge(multiset<key_type, C2, allocator_type>& source);
+// template <class C2>
+// void merge(multiset<key_type, C2, allocator_type>&& source);
+
+#include <set>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Set>
+bool set_equal(const Set& set, Set other)
+{
+ return set == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct throw_comparator
+{
+ bool& should_throw_;
+
+ throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
+
+ template <class T>
+ bool operator()(const T& lhs, const T& rhs) const
+ {
+ if (should_throw_)
+ throw 0;
+ return lhs < rhs;
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::set<int> src{1, 3, 5};
+ std::set<int> dst{2, 4, 5};
+ dst.merge(src);
+ assert(set_equal(src, {5}));
+ assert(set_equal(dst, {1, 2, 3, 4, 5}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::set<Counter<int>, throw_comparator> set_type;
+ set_type src({1, 3, 5}, throw_comparator(do_throw));
+ set_type dst({2, 4, 5}, throw_comparator(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(set_equal(src, set_type({1, 3, 5}, throw_comparator(do_throw))));
+ assert(set_equal(dst, set_type({2, 4, 5}, throw_comparator(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct comparator
+ {
+ comparator() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ {
+ typedef std::set<Counter<int>, std::less<Counter<int>>> first_set_type;
+ typedef std::set<Counter<int>, comparator> second_set_type;
+ typedef std::multiset<Counter<int>, comparator> third_set_type;
+
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(set_equal(first, {1, 2, 3, 4}));
+ assert(set_equal(second, {2, 3}));
+ assert(set_equal(third, {1, 3}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(set_equal(first, {1, 2, 3, 4}));
+ assert(set_equal(second, {2, 3}));
+ assert(set_equal(third, {1, 3}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::set<int> first;
+ {
+ std::set<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::multiset<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp b/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..a55a38c2d568
--- /dev/null
+++ b/test/std/containers/associative/set/set.erasure/erase_if.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <set>
+
+// template <class T, class Compare, class Allocator, class Predicate>
+// void erase_if(set<T, Compare, Allocator>& c, Predicate pred);
+
+#include <set>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::set<int>>();
+ test<std::set<int, std::less<int>, min_allocator<int>>> ();
+ test<std::set<int, std::less<int>, test_allocator<int>>> ();
+
+ test<std::set<long>>();
+ test<std::set<double>>();
+}
diff --git a/test/std/containers/container.adaptors/queue/queue.defn/emplace.pass.cpp b/test/std/containers/container.adaptors/queue/queue.defn/emplace.pass.cpp
index ead9ad0bcdf8..25f6bc76e1aa 100644
--- a/test/std/containers/container.adaptors/queue/queue.defn/emplace.pass.cpp
+++ b/test/std/containers/container.adaptors/queue/queue.defn/emplace.pass.cpp
@@ -43,9 +43,9 @@ int main()
test_return_type<std::queue<int> > ();
test_return_type<std::queue<int, std::list<int> > > ();
- typedef Emplaceable T;
std::queue<Emplaceable> q;
#if TEST_STD_VER > 14
+ typedef Emplaceable T;
T& r1 = q.emplace(1, 2.5);
assert(&r1 == &q.back());
T& r2 = q.emplace(2, 3.5);
diff --git a/test/std/containers/container.adaptors/stack/stack.defn/emplace.pass.cpp b/test/std/containers/container.adaptors/stack/stack.defn/emplace.pass.cpp
index bb6ff8f91670..6830cb716283 100644
--- a/test/std/containers/container.adaptors/stack/stack.defn/emplace.pass.cpp
+++ b/test/std/containers/container.adaptors/stack/stack.defn/emplace.pass.cpp
@@ -42,9 +42,9 @@ int main()
test_return_type<std::stack<int> > ();
test_return_type<std::stack<int, std::vector<int> > > ();
- typedef Emplaceable T;
std::stack<Emplaceable> q;
#if TEST_STD_VER > 14
+ typedef Emplaceable T;
T& r1 = q.emplace(1, 2.5);
assert(&r1 == &q.top());
T& r2 = q.emplace(2, 3.5);
diff --git a/test/std/containers/container.node/node_handle.pass.cpp b/test/std/containers/container.node/node_handle.pass.cpp
index 6314ec1fb771..1c815a4682dd 100644
--- a/test/std/containers/container.node/node_handle.pass.cpp
+++ b/test/std/containers/container.node/node_handle.pass.cpp
@@ -121,10 +121,12 @@ void test_node_handle_operations_multi()
assert(nt2.empty());
}
+template <class> void test_typedef() {}
+
template <class Container>
void test_insert_return_type()
{
- using irt_type = typename Container::insert_return_type;
+ test_typedef<typename Container::insert_return_type>();
}
int main()
diff --git a/test/std/containers/map_allocator_requirement_test_templates.h b/test/std/containers/map_allocator_requirement_test_templates.h
index 2ae3a2e3c87a..374970d48d18 100644
--- a/test/std/containers/map_allocator_requirement_test_templates.h
+++ b/test/std/containers/map_allocator_requirement_test_templates.h
@@ -33,10 +33,6 @@ template <class Container>
void testMapInsert()
{
typedef typename Container::value_type ValueTp;
- typedef typename Container::key_type Key;
- typedef typename Container::mapped_type Mapped;
- typedef Container C;
- typedef std::pair<typename C::iterator, bool> R;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -297,8 +293,6 @@ void testMapEmplace()
typedef typename Container::key_type Key;
typedef typename Container::mapped_type Mapped;
typedef typename std::pair<Key, Mapped> NonConstKeyPair;
- typedef Container C;
- typedef std::pair<typename C::iterator, bool> R;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -630,7 +624,6 @@ template <class Container>
void testMultimapInsert()
{
typedef typename Container::value_type ValueTp;
- typedef Container C;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -704,7 +697,6 @@ template <class Container>
void testMultimapInsertHint()
{
typedef typename Container::value_type ValueTp;
- typedef Container C;
ConstructController* cc = getConstructController();
cc->reset();
{
diff --git a/test/std/containers/sequences/array/array.data/data.pass.cpp b/test/std/containers/sequences/array/array.data/data.pass.cpp
index 714894308f00..ba2c571ebacf 100644
--- a/test/std/containers/sequences/array/array.data/data.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data.pass.cpp
@@ -13,12 +13,19 @@
#include <array>
#include <cassert>
+#include <cstddef> // for std::max_align_t
+
#include "test_macros.h"
// std::array is explicitly allowed to be initialized with A a = { init-list };.
// Disable the missing braces warning for this reason.
#include "disable_missing_braces_warning.h"
+struct NoDefault {
+ NoDefault(int) {}
+};
+
+
int main()
{
{
@@ -35,7 +42,7 @@ int main()
typedef std::array<T, 0> C;
C c = {};
T* p = c.data();
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
}
{
typedef double T;
@@ -43,25 +50,22 @@ int main()
C c = {{}};
const T* p = c.data();
static_assert((std::is_same<decltype(c.data()), const T*>::value), "");
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
}
{
typedef std::max_align_t T;
typedef std::array<T, 0> C;
const C c = {};
const T* p = c.data();
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
assert(pint % TEST_ALIGNOF(std::max_align_t) == 0);
}
{
- struct NoDefault {
- NoDefault(int) {}
- };
typedef NoDefault T;
typedef std::array<T, 0> C;
C c = {};
T* p = c.data();
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
}
}
diff --git a/test/std/containers/sequences/array/array.data/data_const.pass.cpp b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
index b99bf6af8627..f46352564973 100644
--- a/test/std/containers/sequences/array/array.data/data_const.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
@@ -13,6 +13,7 @@
#include <array>
#include <cassert>
+#include <cstddef> // for std::max_align_t
#include "test_macros.h"
@@ -20,6 +21,10 @@
// Disable the missing braces warning for this reason.
#include "disable_missing_braces_warning.h"
+struct NoDefault {
+ NoDefault(int) {}
+};
+
int main()
{
{
@@ -39,21 +44,18 @@ int main()
(void)p; // to placate scan-build
}
{
- struct NoDefault {
- NoDefault(int) {}
- };
typedef NoDefault T;
typedef std::array<T, 0> C;
const C c = {};
const T* p = c.data();
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
}
{
typedef std::max_align_t T;
typedef std::array<T, 0> C;
const C c = {};
const T* p = c.data();
- assert(p != nullptr);
+ LIBCPP_ASSERT(p != nullptr);
std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
assert(pint % TEST_ALIGNOF(std::max_align_t) == 0);
}
diff --git a/test/std/containers/sequences/array/array.tuple/get.fail.cpp b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
index 45e1d2b46b0f..a7e56fccef01 100644
--- a/test/std/containers/sequences/array/array.tuple/get.fail.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
@@ -31,6 +31,6 @@ int main()
typedef std::array<T, 3> C;
C c = {1, 2, 3.5};
std::get<3>(c) = 5.5; // expected-note {{requested here}}
- // expected-error@array:* {{static_assert failed "Index out of bounds in std::get<> (std::array)"}}
+ // expected-error-re@array:* {{static_assert failed{{( due to requirement '3U[L]{0,2} < 3U[L]{0,2}')?}} "Index out of bounds in std::get<> (std::array)"}}
}
}
diff --git a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp
index c9fe695f9cbd..2139fc1ad486 100644
--- a/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp
+++ b/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp
@@ -30,6 +30,6 @@ int main()
typedef double T;
typedef std::array<T, 3> C;
std::tuple_element<3, C> foo; // expected-note {{requested here}}
- // expected-error@array:* {{static_assert failed "Index out of bounds in std::tuple_element<> (std::array)"}}
+ // expected-error-re@array:* {{static_assert failed{{( due to requirement '3U[L]{0,2} < 3U[L]{0,2}')?}} "Index out of bounds in std::tuple_element<> (std::array)"}}
}
}
diff --git a/test/std/containers/sequences/array/begin.pass.cpp b/test/std/containers/sequences/array/begin.pass.cpp
index 282a947fefec..37c6b5eecde2 100644
--- a/test/std/containers/sequences/array/begin.pass.cpp
+++ b/test/std/containers/sequences/array/begin.pass.cpp
@@ -14,10 +14,16 @@
#include <array>
#include <cassert>
+#include "test_macros.h"
+
// std::array is explicitly allowed to be initialized with A a = { init-list };.
// Disable the missing braces warning for this reason.
#include "disable_missing_braces_warning.h"
+struct NoDefault {
+ NoDefault(int) {}
+};
+
int main()
{
@@ -33,12 +39,14 @@ int main()
assert(c[0] == 5.5);
}
{
- struct NoDefault {
- NoDefault(int) {}
- };
typedef NoDefault T;
typedef std::array<T, 0> C;
C c = {};
- assert(c.begin() == c.end());
+ C::iterator ib, ie;
+ ib = c.begin();
+ ie = c.end();
+ assert(ib == ie);
+ LIBCPP_ASSERT(ib != nullptr);
+ LIBCPP_ASSERT(ie != nullptr);
}
}
diff --git a/test/std/containers/sequences/array/compare.pass.cpp b/test/std/containers/sequences/array/compare.pass.cpp
index c8bcf75a0934..5d2bdc50f261 100644
--- a/test/std/containers/sequences/array/compare.pass.cpp
+++ b/test/std/containers/sequences/array/compare.pass.cpp
@@ -9,6 +9,7 @@
// <array>
+// These are all constexpr in C++20
// bool operator==(array<T, N> const&, array<T, N> const&);
// bool operator!=(array<T, N> const&, array<T, N> const&);
// bool operator<(array<T, N> const&, array<T, N> const&);
@@ -22,24 +23,12 @@
#include <cassert>
#include "test_macros.h"
+#include "test_comparisons.h"
// std::array is explicitly allowed to be initialized with A a = { init-list };.
// Disable the missing braces warning for this reason.
#include "disable_missing_braces_warning.h"
-template <class Array>
-void test_compare(const Array& LHS, const Array& RHS) {
- typedef std::vector<typename Array::value_type> Vector;
- const Vector LHSV(LHS.begin(), LHS.end());
- const Vector RHSV(RHS.begin(), RHS.end());
- assert((LHS == RHS) == (LHSV == RHSV));
- assert((LHS != RHS) == (LHSV != RHSV));
- assert((LHS < RHS) == (LHSV < RHSV));
- assert((LHS <= RHS) == (LHSV <= RHSV));
- assert((LHS > RHS) == (LHSV > RHSV));
- assert((LHS >= RHS) == (LHSV >= RHSV));
-}
-
int main()
{
{
@@ -49,15 +38,25 @@ int main()
C c2 = {1, 2, 3};
C c3 = {3, 2, 1};
C c4 = {1, 2, 1};
- test_compare(c1, c2);
- test_compare(c1, c3);
- test_compare(c1, c4);
+ assert(testComparisons6(c1, c2, true, false));
+ assert(testComparisons6(c1, c3, false, true));
+ assert(testComparisons6(c1, c4, false, false));
}
{
typedef int T;
typedef std::array<T, 0> C;
C c1 = {};
C c2 = {};
- test_compare(c1, c2);
+ assert(testComparisons6(c1, c2, true, false));
+ }
+
+#if TEST_STD_VER > 17
+ {
+ constexpr std::array<int, 3> a1 = {1, 2, 3};
+ constexpr std::array<int, 3> a2 = {2, 3, 4};
+ static_assert(testComparisons6(a1, a1, true, false), "");
+ static_assert(testComparisons6(a1, a2, false, true), "");
+ static_assert(testComparisons6(a2, a1, false, false), "");
}
+#endif
}
diff --git a/test/std/containers/sequences/array/size_and_alignment.pass.cpp b/test/std/containers/sequences/array/size_and_alignment.pass.cpp
index 966d063fe17a..d73182bd5cac 100644
--- a/test/std/containers/sequences/array/size_and_alignment.pass.cpp
+++ b/test/std/containers/sequences/array/size_and_alignment.pass.cpp
@@ -58,8 +58,6 @@ struct TEST_ALIGNAS(TEST_ALIGNOF(std::max_align_t) * 2) TestType2 {
char data[1000];
};
-//static_assert(sizeof(void*) == 4, "");
-
int main() {
test_type<char>();
test_type<int>();
diff --git a/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
index 11ce9d2f6899..2365d4e11b02 100644
--- a/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
@@ -30,16 +30,16 @@ int main() {
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::deque<int, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::deque<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp b/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp
new file mode 100644
index 000000000000..9a8c698a5ffb
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <deque>
+
+// template <class T, class Allocator, class U>
+// void erase(deque<T, Allocator>& c, const U& value);
+
+
+#include <deque>
+#include <optional>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class U>
+void
+test0(S s, U val, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase(s, val)));
+ std::erase(s, val);
+ assert(s == expected);
+}
+
+template <class S>
+void test()
+{
+
+ test0(S(), 1, S());
+
+ test0(S({1}), 1, S());
+ test0(S({1}), 2, S({1}));
+
+ test0(S({1,2}), 1, S({2}));
+ test0(S({1,2}), 2, S({1}));
+ test0(S({1,2}), 3, S({1,2}));
+ test0(S({1,1}), 1, S());
+ test0(S({1,1}), 3, S({1,1}));
+
+ test0(S({1,2,3}), 1, S({2,3}));
+ test0(S({1,2,3}), 2, S({1,3}));
+ test0(S({1,2,3}), 3, S({1,2}));
+ test0(S({1,2,3}), 4, S({1,2,3}));
+
+ test0(S({1,1,1}), 1, S());
+ test0(S({1,1,1}), 2, S({1,1,1}));
+ test0(S({1,1,2}), 1, S({2}));
+ test0(S({1,1,2}), 2, S({1,1}));
+ test0(S({1,1,2}), 3, S({1,1,2}));
+ test0(S({1,2,2}), 1, S({2,2}));
+ test0(S({1,2,2}), 2, S({1}));
+ test0(S({1,2,2}), 3, S({1,2,2}));
+
+// Test cross-type erasure
+ using opt = std::optional<typename S::value_type>;
+ test0(S({1,2,1}), opt(), S({1,2,1}));
+ test0(S({1,2,1}), opt(1), S({2}));
+ test0(S({1,2,1}), opt(2), S({1,1}));
+ test0(S({1,2,1}), opt(3), S({1,2,1}));
+}
+
+int main()
+{
+ test<std::deque<int>>();
+ test<std::deque<int, min_allocator<int>>> ();
+ test<std::deque<int, test_allocator<int>>> ();
+
+ test<std::deque<long>>();
+ test<std::deque<double>>();
+}
diff --git a/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp b/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..a090eb6947d0
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.erasure/erase_if.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <deque>
+
+// template <class T, class Allocator, class Predicate>
+// void erase_if(deque<T, Allocator>& c, Predicate pred);
+
+#include <deque>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+ test0(S({1,1}), is1, S());
+ test0(S({1,1}), is3, S({1,1}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,1,1}), is1, S());
+ test0(S({1,1,1}), is2, S({1,1,1}));
+ test0(S({1,1,2}), is1, S({2}));
+ test0(S({1,1,2}), is2, S({1,1}));
+ test0(S({1,1,2}), is3, S({1,1,2}));
+ test0(S({1,2,2}), is1, S({2,2}));
+ test0(S({1,2,2}), is2, S({1}));
+ test0(S({1,2,2}), is3, S({1,2,2}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::deque<int>>();
+ test<std::deque<int, min_allocator<int>>> ();
+ test<std::deque<int, test_allocator<int>>> ();
+
+ test<std::deque<long>>();
+ test<std::deque<double>>();
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/clear.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/clear.pass.cpp
new file mode 100644
index 000000000000..943b6e8e11ca
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.modifiers/clear.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// void clear() noexcept;
+
+#include <deque>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../../NotConstructible.h"
+#include "min_allocator.h"
+
+int main()
+{
+ {
+ typedef NotConstructible T;
+ typedef std::deque<T> C;
+ C c;
+ ASSERT_NOEXCEPT(c.clear());
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+ }
+ {
+ typedef int T;
+ typedef std::deque<T> C;
+ const T t[] = {0, 1, 2, 3, 4};
+ C c(std::begin(t), std::end(t));
+
+ ASSERT_NOEXCEPT(c.clear());
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+ }
+#if TEST_STD_VER >= 11
+ {
+ typedef NotConstructible T;
+ typedef std::deque<T, min_allocator<T>> C;
+ C c;
+ ASSERT_NOEXCEPT(c.clear());
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+ }
+ {
+ typedef int T;
+ typedef std::deque<T, min_allocator<T>> C;
+ const T t[] = {0, 1, 2, 3, 4};
+ C c(std::begin(t), std::end(t));
+
+ ASSERT_NOEXCEPT(c.clear());
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+
+ c.clear();
+ assert(distance(c.begin(), c.end()) == 0);
+ }
+#endif
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
index def032c2705a..3ed17ab3f78c 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
@@ -18,6 +18,23 @@
#include <cstddef>
#include "min_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct Throws {
+ Throws() : v_(0) {}
+ Throws(int v) : v_(v) {}
+ Throws(const Throws &rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
+ Throws( Throws &&rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
+ Throws& operator=(const Throws &rhs) { v_ = rhs.v_; return *this; }
+ Throws& operator=( Throws &&rhs) { v_ = rhs.v_; return *this; }
+ int v_;
+
+ static bool sThrows;
+ };
+
+bool Throws::sThrows = false;
+#endif
template <class C>
C
@@ -90,4 +107,19 @@ int main()
testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
}
#endif
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+// Test for LWG2953:
+// Throws: Nothing unless an exception is thrown by the assignment operator of T.
+// (which includes move assignment)
+ {
+ Throws arr[] = {1, 2, 3};
+ std::deque<Throws> v(arr, arr+3);
+ Throws::sThrows = true;
+ v.erase(v.begin());
+ v.erase(--v.end());
+ v.erase(v.begin());
+ assert(v.size() == 0);
+ }
+#endif
}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
index 338c66d81f97..6556ced1a65a 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
@@ -20,6 +20,24 @@
#include <cstddef>
#include "min_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct Throws {
+ Throws() : v_(0) {}
+ Throws(int v) : v_(v) {}
+ Throws(const Throws &rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
+ Throws( Throws &&rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
+ Throws& operator=(const Throws &rhs) { v_ = rhs.v_; return *this; }
+ Throws& operator=( Throws &&rhs) { v_ = rhs.v_; return *this; }
+ int v_;
+
+ static bool sThrows;
+ };
+
+bool Throws::sThrows = false;
+#endif
+
template <class C>
C
@@ -96,4 +114,18 @@ int main()
testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
}
#endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+// Test for LWG2953:
+// Throws: Nothing unless an exception is thrown by the assignment operator of T.
+// (which includes move assignment)
+ {
+ Throws arr[] = {1, 2, 3};
+ std::deque<Throws> v(arr, arr+3);
+ Throws::sThrows = true;
+ v.erase(v.begin(), --v.end());
+ assert(v.size() == 1);
+ v.erase(v.begin(), v.end());
+ assert(v.size() == 0);
+ }
+#endif
}
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp
new file mode 100644
index 000000000000..0163b8607cb2
--- /dev/null
+++ b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <forward_list>
+
+// template <class T, class Allocator, class U>
+// void erase(forward_list<T, Allocator>& c, const U& value);
+
+
+#include <forward_list>
+#include <optional>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class U>
+void
+test0(S s, U val, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase(s, val)));
+ std::erase(s, val);
+ assert(s == expected);
+}
+
+template <class S>
+void test()
+{
+
+ test0(S(), 1, S());
+
+ test0(S({1}), 1, S());
+ test0(S({1}), 2, S({1}));
+
+ test0(S({1,2}), 1, S({2}));
+ test0(S({1,2}), 2, S({1}));
+ test0(S({1,2}), 3, S({1,2}));
+ test0(S({1,1}), 1, S());
+ test0(S({1,1}), 3, S({1,1}));
+
+ test0(S({1,2,3}), 1, S({2,3}));
+ test0(S({1,2,3}), 2, S({1,3}));
+ test0(S({1,2,3}), 3, S({1,2}));
+ test0(S({1,2,3}), 4, S({1,2,3}));
+
+ test0(S({1,1,1}), 1, S());
+ test0(S({1,1,1}), 2, S({1,1,1}));
+ test0(S({1,1,2}), 1, S({2}));
+ test0(S({1,1,2}), 2, S({1,1}));
+ test0(S({1,1,2}), 3, S({1,1,2}));
+ test0(S({1,2,2}), 1, S({2,2}));
+ test0(S({1,2,2}), 2, S({1}));
+ test0(S({1,2,2}), 3, S({1,2,2}));
+
+// Test cross-type erasure
+ using opt = std::optional<typename S::value_type>;
+ test0(S({1,2,1}), opt(), S({1,2,1}));
+ test0(S({1,2,1}), opt(1), S({2}));
+ test0(S({1,2,1}), opt(2), S({1,1}));
+ test0(S({1,2,1}), opt(3), S({1,2,1}));
+}
+
+int main()
+{
+ test<std::forward_list<int>>();
+ test<std::forward_list<int, min_allocator<int>>> ();
+ test<std::forward_list<int, test_allocator<int>>> ();
+
+ test<std::forward_list<long>>();
+ test<std::forward_list<double>>();
+}
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..69685d2d35f2
--- /dev/null
+++ b/test/std/containers/sequences/forwardlist/forwardlist.erasure/erase_if.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <forward_list>
+
+// template <class T, class Allocator, class Predicate>
+// void erase_if(forward_list<T, Allocator>& c, Predicate pred);
+
+#include <forward_list>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+ test0(S({1,1}), is1, S());
+ test0(S({1,1}), is3, S({1,1}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,1,1}), is1, S());
+ test0(S({1,1,1}), is2, S({1,1,1}));
+ test0(S({1,1,2}), is1, S({2}));
+ test0(S({1,1,2}), is2, S({1,1}));
+ test0(S({1,1,2}), is3, S({1,1,2}));
+ test0(S({1,2,2}), is1, S({2,2}));
+ test0(S({1,2,2}), is2, S({1}));
+ test0(S({1,2,2}), is3, S({1,2,2}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::forward_list<int>>();
+ test<std::forward_list<int, min_allocator<int>>> ();
+ test<std::forward_list<int, test_allocator<int>>> ();
+
+ test<std::forward_list<long>>();
+ test<std::forward_list<double>>();
+}
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
index 0e625ac76a02..6cdf8d57ace3 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
@@ -9,11 +9,12 @@
// <forward_list>
-// void clear();
+// void clear() noexcept;
#include <forward_list>
#include <cassert>
+#include "test_macros.h"
#include "../../../NotConstructible.h"
#include "min_allocator.h"
@@ -23,6 +24,7 @@ int main()
typedef NotConstructible T;
typedef std::forward_list<T> C;
C c;
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(distance(c.begin(), c.end()) == 0);
}
@@ -32,6 +34,7 @@ int main()
const T t[] = {0, 1, 2, 3, 4};
C c(std::begin(t), std::end(t));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(distance(c.begin(), c.end()) == 0);
@@ -43,6 +46,7 @@ int main()
typedef NotConstructible T;
typedef std::forward_list<T, min_allocator<T>> C;
C c;
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(distance(c.begin(), c.end()) == 0);
}
@@ -52,6 +56,7 @@ int main()
const T t[] = {0, 1, 2, 3, 4};
C c(std::begin(t), std::end(t));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(distance(c.begin(), c.end()) == 0);
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
index 356e0d657c35..297e2725a158 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
@@ -88,7 +88,6 @@ int main()
{
// Test that the allocator's construct method is being used to
// construct the new elements and that it's called exactly N times.
- typedef int T;
typedef std::forward_list<int, ContainerTestAllocator<int, int>> Container;
ConstructController* cc = getConstructController();
cc->reset();
diff --git a/test/std/containers/sequences/forwardlist/max_size.pass.cpp b/test/std/containers/sequences/forwardlist/max_size.pass.cpp
index 916d12a9f67c..dc35ac5f5da5 100644
--- a/test/std/containers/sequences/forwardlist/max_size.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/max_size.pass.cpp
@@ -31,16 +31,16 @@ int main()
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::forward_list<int, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::forward_list<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp b/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp
index bd1b65e63d70..e8a48a2db747 100644
--- a/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp
+++ b/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp
@@ -30,16 +30,16 @@ int main() {
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::list<int, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::list<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp
index 3cdcc73627b8..d2c7fa023eb8 100644
--- a/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp
+++ b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp
@@ -183,7 +183,6 @@ void test_ctor_under_alloc() {
int arr2[] = {1, 101, 42};
{
using C = TCT::list<>;
- using T = typename C::value_type;
using It = forward_iterator<int*>;
{
ExpectConstructGuard<int&> G(1);
@@ -196,7 +195,6 @@ void test_ctor_under_alloc() {
}
{
using C = TCT::list<>;
- using T = typename C::value_type;
using It = input_iterator<int*>;
{
ExpectConstructGuard<int&> G(1);
@@ -216,7 +214,6 @@ void test_ctor_under_alloc_with_alloc() {
int arr2[] = {1, 101, 42};
{
using C = TCT::list<>;
- using T = typename C::value_type;
using It = forward_iterator<int*>;
using Alloc = typename C::allocator_type;
Alloc a;
@@ -231,7 +228,6 @@ void test_ctor_under_alloc_with_alloc() {
}
{
using C = TCT::list<>;
- using T = typename C::value_type;
using It = input_iterator<int*>;
using Alloc = typename C::allocator_type;
Alloc a;
diff --git a/test/std/containers/sequences/list/list.erasure/erase.pass.cpp b/test/std/containers/sequences/list/list.erasure/erase.pass.cpp
new file mode 100644
index 000000000000..a9f65c0537eb
--- /dev/null
+++ b/test/std/containers/sequences/list/list.erasure/erase.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <list>
+
+// template <class T, class Allocator, class U>
+// void erase(list<T, Allocator>& c, const U& value);
+
+
+#include <list>
+#include <optional>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class U>
+void
+test0(S s, U val, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase(s, val)));
+ std::erase(s, val);
+ assert(s == expected);
+}
+
+template <class S>
+void test()
+{
+
+ test0(S(), 1, S());
+
+ test0(S({1}), 1, S());
+ test0(S({1}), 2, S({1}));
+
+ test0(S({1,2}), 1, S({2}));
+ test0(S({1,2}), 2, S({1}));
+ test0(S({1,2}), 3, S({1,2}));
+ test0(S({1,1}), 1, S());
+ test0(S({1,1}), 3, S({1,1}));
+
+ test0(S({1,2,3}), 1, S({2,3}));
+ test0(S({1,2,3}), 2, S({1,3}));
+ test0(S({1,2,3}), 3, S({1,2}));
+ test0(S({1,2,3}), 4, S({1,2,3}));
+
+ test0(S({1,1,1}), 1, S());
+ test0(S({1,1,1}), 2, S({1,1,1}));
+ test0(S({1,1,2}), 1, S({2}));
+ test0(S({1,1,2}), 2, S({1,1}));
+ test0(S({1,1,2}), 3, S({1,1,2}));
+ test0(S({1,2,2}), 1, S({2,2}));
+ test0(S({1,2,2}), 2, S({1}));
+ test0(S({1,2,2}), 3, S({1,2,2}));
+
+// Test cross-type erasure
+ using opt = std::optional<typename S::value_type>;
+ test0(S({1,2,1}), opt(), S({1,2,1}));
+ test0(S({1,2,1}), opt(1), S({2}));
+ test0(S({1,2,1}), opt(2), S({1,1}));
+ test0(S({1,2,1}), opt(3), S({1,2,1}));
+}
+
+int main()
+{
+ test<std::list<int>>();
+ test<std::list<int, min_allocator<int>>> ();
+ test<std::list<int, test_allocator<int>>> ();
+
+ test<std::list<long>>();
+ test<std::list<double>>();
+}
diff --git a/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp b/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..99b1c6530f96
--- /dev/null
+++ b/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <list>
+
+// template <class T, class Allocator, class Predicate>
+// void erase_if(list<T, Allocator>& c, Predicate pred);
+
+#include <list>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+ test0(S({1,1}), is1, S());
+ test0(S({1,1}), is3, S({1,1}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,1,1}), is1, S());
+ test0(S({1,1,1}), is2, S({1,1,1}));
+ test0(S({1,1,2}), is1, S({2}));
+ test0(S({1,1,2}), is2, S({1,1}));
+ test0(S({1,1,2}), is3, S({1,1,2}));
+ test0(S({1,2,2}), is1, S({2,2}));
+ test0(S({1,2,2}), is2, S({1}));
+ test0(S({1,2,2}), is3, S({1,2,2}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::list<int>>();
+ test<std::list<int, min_allocator<int>>> ();
+ test<std::list<int, test_allocator<int>>> ();
+
+ test<std::list<long>>();
+ test<std::list<double>>();
+}
diff --git a/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp b/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp
index 5d8c41fa1976..1d7cb80eb65b 100644
--- a/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp
@@ -9,11 +9,12 @@
// <list>
-// void clear();
+// void clear() noexcept;
#include <list>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -21,6 +22,7 @@ int main()
{
int a[] = {1, 2, 3};
std::list<int> c(a, a+3);
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.empty());
}
@@ -28,6 +30,7 @@ int main()
{
int a[] = {1, 2, 3};
std::list<int, min_allocator<int>> c(a, a+3);
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.empty());
}
diff --git a/test/std/containers/sequences/list/list.ops/merge.pass.cpp b/test/std/containers/sequences/list/list.ops/merge.pass.cpp
index 7c1287706f35..af4b02ce35b1 100644
--- a/test/std/containers/sequences/list/list.ops/merge.pass.cpp
+++ b/test/std/containers/sequences/list/list.ops/merge.pass.cpp
@@ -10,6 +10,7 @@
// <list>
// void merge(list& x);
+// If (&addressof(x) == this) does nothing; otherwise ...
#include <list>
#include <cassert>
@@ -26,7 +27,16 @@ int main()
std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
c1.merge(c2);
assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0])));
+ assert(c2.empty());
}
+
+ {
+ int a1[] = {1, 3, 7, 9, 10};
+ std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+ c1.merge(c1);
+ assert((c1 == std::list<int>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+ }
+
#if TEST_STD_VER >= 11
{
int a1[] = {1, 3, 7, 9, 10};
@@ -36,6 +46,7 @@ int main()
std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
c1.merge(c2);
assert((c1 == std::list<int, min_allocator<int>>(a3, a3+sizeof(a3)/sizeof(a3[0]))));
+ assert(c2.empty());
}
#endif
}
diff --git a/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp b/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp
index 838ff22b3a53..20ddbef62053 100644
--- a/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp
+++ b/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp
@@ -10,6 +10,7 @@
// <list>
// template <class Compare> void merge(list& x, Compare comp);
+// If (&addressof(x) == this) does nothing; otherwise ...
#include <list>
#include <functional>
@@ -27,7 +28,15 @@ int main()
std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
c1.merge(c2, std::greater<int>());
assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0])));
+ assert(c2.empty());
}
+ {
+ int a1[] = {10, 9, 7, 3, 1};
+ std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+ c1.merge(c1, std::greater<int>());
+ assert((c1 == std::list<int>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+ }
+
#if TEST_STD_VER >= 11
{
int a1[] = {10, 9, 7, 3, 1};
@@ -37,6 +46,7 @@ int main()
std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
c1.merge(c2, std::greater<int>());
assert((c1 == std::list<int, min_allocator<int>>(a3, a3+sizeof(a3)/sizeof(a3[0]))));
+ assert(c2.empty());
}
#endif
}
diff --git a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
index 0f51c219ee49..80bfce1ad9a4 100644
--- a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
@@ -7,10 +7,15 @@
//
//===----------------------------------------------------------------------===//
-// <vector>
// vector<bool>
-// vector(const Alloc& = Alloc());
+// vector();
+// vector(const Alloc&);
+
+// This tests a conforming extension
+// For vector<>, this was added to the standard by N4258,
+// but vector<bool> was not changed.
+
#include <vector>
#include <cassert>
@@ -24,9 +29,9 @@ void
test0()
{
#if TEST_STD_VER > 14
- static_assert((noexcept(C{})), "" );
+ LIBCPP_STATIC_ASSERT((noexcept(C{})), "" );
#elif TEST_STD_VER >= 11
- static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" );
+ LIBCPP_STATIC_ASSERT((noexcept(C()) == noexcept(typename C::allocator_type())), "" );
#endif
C c;
LIBCPP_ASSERT(c.__invariants());
@@ -45,9 +50,9 @@ void
test1(const typename C::allocator_type& a)
{
#if TEST_STD_VER > 14
- static_assert((noexcept(C{typename C::allocator_type{}})), "" );
+ LIBCPP_STATIC_ASSERT((noexcept(C{typename C::allocator_type{}})), "" );
#elif TEST_STD_VER >= 11
- static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible<typename C::allocator_type>::value), "" );
+ LIBCPP_STATIC_ASSERT((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible<typename C::allocator_type>::value), "" );
#endif
C c(a);
LIBCPP_ASSERT(c.__invariants());
diff --git a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
index 4e71df37421e..e2d94e225674 100644
--- a/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/default_noexcept.pass.cpp
@@ -6,6 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
// <vector>
@@ -13,8 +14,9 @@
// noexcept(is_nothrow_default_constructible<allocator_type>::value);
// This tests a conforming extension
+// For vector<>, this was added to the standard by N4258,
+// but vector<bool> was not changed.
-// UNSUPPORTED: c++98, c++03
#include <vector>
#include <cassert>
@@ -40,7 +42,6 @@ int main()
typedef std::vector<bool, test_allocator<bool>> C;
static_assert(std::is_nothrow_default_constructible<C>::value, "");
}
-#endif // _LIBCPP_VERSION
{
typedef std::vector<bool, other_allocator<bool>> C;
static_assert(!std::is_nothrow_default_constructible<C>::value, "");
@@ -49,4 +50,5 @@ int main()
typedef std::vector<bool, some_alloc<bool>> C;
static_assert(!std::is_nothrow_default_constructible<C>::value, "");
}
+#endif // _LIBCPP_VERSION
}
diff --git a/test/std/containers/sequences/vector.bool/move.pass.cpp b/test/std/containers/sequences/vector.bool/move.pass.cpp
index ab2b7ce6d316..b3663c759a87 100644
--- a/test/std/containers/sequences/vector.bool/move.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/move.pass.cpp
@@ -26,8 +26,8 @@ int main()
std::vector<bool, test_allocator<bool> > lo(test_allocator<bool>(5));
for (int i = 1; i <= 3; ++i)
{
- l.push_back(i);
- lo.push_back(i);
+ l.push_back(true);
+ lo.push_back(true);
}
std::vector<bool, test_allocator<bool> > l2 = std::move(l);
assert(l2 == lo);
@@ -39,8 +39,8 @@ int main()
std::vector<bool, other_allocator<bool> > lo(other_allocator<bool>(5));
for (int i = 1; i <= 3; ++i)
{
- l.push_back(i);
- lo.push_back(i);
+ l.push_back(true);
+ lo.push_back(true);
}
std::vector<bool, other_allocator<bool> > l2 = std::move(l);
assert(l2 == lo);
@@ -52,8 +52,8 @@ int main()
std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{});
for (int i = 1; i <= 3; ++i)
{
- l.push_back(i);
- lo.push_back(i);
+ l.push_back(true);
+ lo.push_back(true);
}
std::vector<bool, min_allocator<bool> > l2 = std::move(l);
assert(l2 == lo);
diff --git a/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp
index 5f7a6268d55c..3ab5cc6a890b 100644
--- a/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp
@@ -31,16 +31,16 @@ int main() {
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::vector<int, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::vector<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
index 88613efe7a2b..60fe2899ac20 100644
--- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -121,7 +121,6 @@ void test_ctor_under_alloc() {
int arr2[] = {1, 101, 42};
{
using C = TCT::vector<>;
- using T = typename C::value_type;
using It = forward_iterator<int*>;
{
ExpectConstructGuard<int&> G(1);
@@ -134,7 +133,6 @@ void test_ctor_under_alloc() {
}
{
using C = TCT::vector<>;
- using T = typename C::value_type;
using It = input_iterator<int*>;
{
ExpectConstructGuard<int&> G(1);
@@ -148,9 +146,40 @@ void test_ctor_under_alloc() {
#endif
}
+// Initialize a vector with a different value type.
+void test_ctor_with_different_value_type() {
+ {
+ // Make sure initialization is performed with each element value, not with
+ // a memory blob.
+ float array[3] = {0.0f, 1.0f, 2.0f};
+ std::vector<int> v(array, array + 3);
+ assert(v[0] == 0);
+ assert(v[1] == 1);
+ assert(v[2] == 2);
+ }
+ struct X { int x; };
+ struct Y { int y; };
+ struct Z : X, Y { int z; };
+ {
+ Z z;
+ Z *array[1] = { &z };
+ // Though the types Z* and Y* are very similar, initialization still cannot
+ // be done with `memcpy`.
+ std::vector<Y*> v(array, array + 1);
+ assert(v[0] == &z);
+ }
+ {
+ // Though the types are different, initialization can be done with `memcpy`.
+ int32_t array[1] = { -1 };
+ std::vector<uint32_t> v(array, array + 1);
+ assert(v[0] == 4294967295);
+ }
+}
+
int main() {
basic_test_cases();
emplaceable_concept_tests(); // See PR34898
test_ctor_under_alloc();
+ test_ctor_with_different_value_type();
}
diff --git a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
index 71743b31d44c..15498ba4135c 100644
--- a/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -134,7 +134,6 @@ void test_ctor_under_alloc() {
int arr2[] = {1, 101, 42};
{
using C = TCT::vector<>;
- using T = typename C::value_type;
using It = forward_iterator<int*>;
using Alloc = typename C::allocator_type;
Alloc a;
@@ -149,7 +148,6 @@ void test_ctor_under_alloc() {
}
{
using C = TCT::vector<>;
- using T = typename C::value_type;
using It = input_iterator<int*>;
using Alloc = typename C::allocator_type;
Alloc a;
diff --git a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
index b244f75f21d4..f8c932a02d63 100644
--- a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
@@ -6,15 +6,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
// <vector>
// vector()
// noexcept(is_nothrow_default_constructible<allocator_type>::value);
-// This tests a conforming extension
+// This *was* a conforming extension, but it was adopted in N4258.
-// UNSUPPORTED: c++98, c++03
#include <vector>
#include <cassert>
diff --git a/test/std/containers/sequences/vector/vector.cons/move.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
index 6938aa679eba..330bcda8b10e 100644
--- a/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
@@ -21,7 +21,6 @@
#include "test_allocator.h"
#include "min_allocator.h"
#include "asan_testing.h"
-#include "verbose_assert.h"
int main()
{
diff --git a/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp b/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp
new file mode 100644
index 000000000000..e88252f1d920
--- /dev/null
+++ b/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <vector>
+
+// template <class T, class Allocator, class U>
+// void erase(vector<T, Allocator>& c, const U& value);
+
+
+#include <vector>
+#include <optional>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class U>
+void
+test0(S s, U val, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase(s, val)));
+ std::erase(s, val);
+ assert(s == expected);
+}
+
+template <class S>
+void test()
+{
+
+ test0(S(), 1, S());
+
+ test0(S({1}), 1, S());
+ test0(S({1}), 2, S({1}));
+
+ test0(S({1,2}), 1, S({2}));
+ test0(S({1,2}), 2, S({1}));
+ test0(S({1,2}), 3, S({1,2}));
+ test0(S({1,1}), 1, S());
+ test0(S({1,1}), 3, S({1,1}));
+
+ test0(S({1,2,3}), 1, S({2,3}));
+ test0(S({1,2,3}), 2, S({1,3}));
+ test0(S({1,2,3}), 3, S({1,2}));
+ test0(S({1,2,3}), 4, S({1,2,3}));
+
+ test0(S({1,1,1}), 1, S());
+ test0(S({1,1,1}), 2, S({1,1,1}));
+ test0(S({1,1,2}), 1, S({2}));
+ test0(S({1,1,2}), 2, S({1,1}));
+ test0(S({1,1,2}), 3, S({1,1,2}));
+ test0(S({1,2,2}), 1, S({2,2}));
+ test0(S({1,2,2}), 2, S({1}));
+ test0(S({1,2,2}), 3, S({1,2,2}));
+
+// Test cross-type erasure
+ using opt = std::optional<typename S::value_type>;
+ test0(S({1,2,1}), opt(), S({1,2,1}));
+ test0(S({1,2,1}), opt(1), S({2}));
+ test0(S({1,2,1}), opt(2), S({1,1}));
+ test0(S({1,2,1}), opt(3), S({1,2,1}));
+}
+
+int main()
+{
+ test<std::vector<int>>();
+ test<std::vector<int, min_allocator<int>>> ();
+ test<std::vector<int, test_allocator<int>>> ();
+
+ test<std::vector<long>>();
+ test<std::vector<double>>();
+}
diff --git a/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp b/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..8025a34071f5
--- /dev/null
+++ b/test/std/containers/sequences/vector/vector.erasure/erase_if.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <vector>
+
+// template <class T, class Allocator, class Predicate>
+// void erase_if(vector<T, Allocator>& c, Predicate pred);
+
+#include <vector>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(), is1, S());
+
+ test0(S({1}), is1, S());
+ test0(S({1}), is2, S({1}));
+
+ test0(S({1,2}), is1, S({2}));
+ test0(S({1,2}), is2, S({1}));
+ test0(S({1,2}), is3, S({1,2}));
+ test0(S({1,1}), is1, S());
+ test0(S({1,1}), is3, S({1,1}));
+
+ test0(S({1,2,3}), is1, S({2,3}));
+ test0(S({1,2,3}), is2, S({1,3}));
+ test0(S({1,2,3}), is3, S({1,2}));
+ test0(S({1,2,3}), is4, S({1,2,3}));
+
+ test0(S({1,1,1}), is1, S());
+ test0(S({1,1,1}), is2, S({1,1,1}));
+ test0(S({1,1,2}), is1, S({2}));
+ test0(S({1,1,2}), is2, S({1,1}));
+ test0(S({1,1,2}), is3, S({1,1,2}));
+ test0(S({1,2,2}), is1, S({2,2}));
+ test0(S({1,2,2}), is2, S({1}));
+ test0(S({1,2,2}), is3, S({1,2,2}));
+
+ test0(S({1,2,3}), True, S());
+ test0(S({1,2,3}), False, S({1,2,3}));
+}
+
+int main()
+{
+ test<std::vector<int>>();
+ test<std::vector<int, min_allocator<int>>> ();
+ test<std::vector<int, test_allocator<int>>> ();
+
+ test<std::vector<long>>();
+ test<std::vector<double>>();
+}
diff --git a/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp
index 5f053eb8565a..5357ba4cb284 100644
--- a/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.modifiers/clear.pass.cpp
@@ -9,11 +9,12 @@
// <vector>
-// void clear();
+// void clear() noexcept;
#include <vector>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
#include "asan_testing.h"
@@ -22,6 +23,7 @@ int main()
{
int a[] = {1, 2, 3};
std::vector<int> c(a, a+3);
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.empty());
LIBCPP_ASSERT(c.__invariants());
@@ -31,6 +33,7 @@ int main()
{
int a[] = {1, 2, 3};
std::vector<int, min_allocator<int>> c(a, a+3);
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.empty());
LIBCPP_ASSERT(c.__invariants());
diff --git a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
index 258b9d9f7517..b54a96d0beda 100644
--- a/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
@@ -25,11 +25,12 @@
int main()
{
{
- std::vector<int> v(100);
+ typedef std::vector<int> V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
- input_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
+ input_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
@@ -42,11 +43,12 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int> v(100);
+ typedef std::vector<int> V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
- forward_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+ forward_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
@@ -59,13 +61,14 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int> v(100);
+ typedef std::vector<int> V;
+ V v(100);
while(v.size() < v.capacity()) v.push_back(0); // force reallocation
size_t sz = v.size();
int a[] = {1, 2, 3, 4, 5};
const unsigned N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
- forward_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+ forward_iterator<const int*>(a+N));
assert(v.size() == sz + N);
assert(i == v.begin() + 10);
std::size_t j;
@@ -77,13 +80,14 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int> v(100);
+ typedef std::vector<int> V;
+ V v(100);
v.reserve(128); // force no reallocation
size_t sz = v.size();
int a[] = {1, 2, 3, 4, 5};
const unsigned N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
- forward_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+ forward_iterator<const int*>(a+N));
assert(v.size() == sz + N);
assert(i == v.begin() + 10);
std::size_t j;
@@ -95,11 +99,12 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int, limited_allocator<int, 308> > v(100);
+ typedef std::vector<int, limited_allocator<int, 308> > V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
- input_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
+ input_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
@@ -112,11 +117,12 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int, limited_allocator<int, 300> > v(100);
+ typedef std::vector<int, limited_allocator<int, 300> > V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
- forward_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+ forward_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
@@ -130,11 +136,12 @@ int main()
}
#if TEST_STD_VER >= 11
{
- std::vector<int, min_allocator<int>> v(100);
+ typedef std::vector<int, min_allocator<int> > V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
- input_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
+ input_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
@@ -147,11 +154,12 @@ int main()
assert(v[j] == 0);
}
{
- std::vector<int, min_allocator<int>> v(100);
+ typedef std::vector<int, min_allocator<int> > V;
+ V v(100);
int a[] = {1, 2, 3, 4, 5};
const int N = sizeof(a)/sizeof(a[0]);
- std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
- forward_iterator<const int*>(a+N));
+ V::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+ forward_iterator<const int*>(a+N));
assert(v.size() == 100 + N);
assert(is_contiguous_container_asan_correct(v));
assert(i == v.begin() + 10);
diff --git a/test/std/containers/set_allocator_requirement_test_templates.h b/test/std/containers/set_allocator_requirement_test_templates.h
index 2e3346f47e2d..517c36d8e958 100644
--- a/test/std/containers/set_allocator_requirement_test_templates.h
+++ b/test/std/containers/set_allocator_requirement_test_templates.h
@@ -32,8 +32,6 @@ template <class Container>
void testSetInsert()
{
typedef typename Container::value_type ValueTp;
- typedef Container C;
- typedef std::pair<typename C::iterator, bool> R;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -146,8 +144,6 @@ template <class Container>
void testSetEmplace()
{
typedef typename Container::value_type ValueTp;
- typedef Container C;
- typedef std::pair<typename C::iterator, bool> R;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -209,7 +205,6 @@ template <class Container>
void testSetEmplaceHint()
{
typedef typename Container::value_type ValueTp;
-
typedef Container C;
typedef typename C::iterator It;
ConstructController* cc = getConstructController();
@@ -289,7 +284,6 @@ template <class Container>
void testMultisetInsert()
{
typedef typename Container::value_type ValueTp;
- typedef Container C;
ConstructController* cc = getConstructController();
cc->reset();
{
@@ -344,11 +338,52 @@ void testMultisetInsert()
{
CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
Container c;
- ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+ ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(1) };
cc->expect<ValueTp&>(3);
c.insert(std::begin(ValueList), std::end(ValueList));
assert(!cc->unchecked());
}
}
+
+template <class Container>
+void testMultisetEmplace()
+{
+ typedef typename Container::value_type ValueTp;
+ ConstructController* cc = getConstructController();
+ cc->reset();
+ {
+ CHECKPOINT("Testing C::emplace(const value_type&)");
+ Container c;
+ const ValueTp v(42);
+ cc->expect<const ValueTp&>();
+ c.emplace(v);
+ assert(!cc->unchecked());
+ }
+ {
+ CHECKPOINT("Testing C::emplace(value_type&)");
+ Container c;
+ ValueTp v(42);
+ cc->expect<ValueTp&>();
+ c.emplace(v);
+ assert(!cc->unchecked());
+ }
+ {
+ CHECKPOINT("Testing C::emplace(value_type&&)");
+ Container c;
+ ValueTp v(42);
+ cc->expect<ValueTp&&>();
+ c.emplace(std::move(v));
+ assert(!cc->unchecked());
+ }
+ {
+ CHECKPOINT("Testing C::emplace(const value_type&&)");
+ Container c;
+ const ValueTp v(42);
+ cc->expect<const ValueTp&&>();
+ c.emplace(std::move(v));
+ assert(!cc->unchecked());
+ }
+}
+
#endif
diff --git a/test/std/containers/unord/unord.map/compare.pass.cpp b/test/std/containers/unord/unord.map/compare.pass.cpp
index cffc1dbd42c1..2761bf17764a 100644
--- a/test/std/containers/unord/unord.map/compare.pass.cpp
+++ b/test/std/containers/unord/unord.map/compare.pass.cpp
@@ -33,8 +33,7 @@ namespace std
};
}
-int
-main()
+int main()
{
typedef std::unordered_map<Key, int> MapT;
typedef MapT::iterator Iter;
diff --git a/test/std/containers/unord/unord.map/erase_if.pass.cpp b/test/std/containers/unord/unord.map/erase_if.pass.cpp
new file mode 100644
index 000000000000..f6a580c2160d
--- /dev/null
+++ b/test/std/containers/unord/unord.map/erase_if.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate>
+// void erase_if(unordered_map<Key, T, Hash, Pred, Allocator>& c, Predicate pred);
+
+#include <unordered_map>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret[v] = v + 10;
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ M e = make<M>(expected);
+ assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end())));
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v.first == 1;};
+ auto is2 = [](auto v) { return v.first == 2;};
+ auto is3 = [](auto v) { return v.first == 3;};
+ auto is4 = [](auto v) { return v.first == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::unordered_map<int, int>>();
+ test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> ();
+ test<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> ();
+
+ test<std::unordered_map<long, short>>();
+ test<std::unordered_map<short, double>>();
+}
+
diff --git a/test/std/containers/unord/unord.map/max_size.pass.cpp b/test/std/containers/unord/unord.map/max_size.pass.cpp
index 152741981461..d01b526836e7 100644
--- a/test/std/containers/unord/unord.map/max_size.pass.cpp
+++ b/test/std/containers/unord/unord.map/max_size.pass.cpp
@@ -36,16 +36,16 @@ int main()
typedef limited_allocator<KV, (size_t)-1> A;
typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, A>
C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::unordered_map<char, int> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
index b793f0934355..c6b92744e313 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
@@ -15,10 +15,12 @@
// unordered_map& operator=(const unordered_map& u);
+#include <algorithm>
#include <unordered_map>
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
index 9fca1f105928..6bfb7bc181e4 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "../../../test_compare.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
index 0d08fae0c3bc..af98b923d3b7 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
index b06e4db1303a..1979dd326df4 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
index 3dbcf4d15823..94c4bca9b869 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
@@ -20,6 +20,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp
index e526b654a197..a17c49d595de 100644
--- a/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.elem/at.pass.cpp
@@ -16,9 +16,10 @@
// mapped_type& at(const key_type& k);
// const mapped_type& at(const key_type& k) const;
-#include <unordered_map>
-#include <string>
#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <unordered_map>
#include "MoveOnly.h"
#include "min_allocator.h"
diff --git a/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp
index 7bc59447a5e6..f7f3a22d5c15 100644
--- a/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp
@@ -119,7 +119,6 @@ int main()
using Container = TCT::unordered_map<>;
using Key = Container::key_type;
using MappedType = Container::mapped_type;
- using ValueTp = Container::value_type;
ConstructController* cc = getConstructController();
cc->reset();
{
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp
index 106423ebfbe9..9212a5e3def3 100644
--- a/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp
@@ -13,12 +13,13 @@
// class Alloc = allocator<pair<const Key, T>>>
// class unordered_map
-// void clear()
+// void clear() noexcept;
#include <unordered_map>
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
P(2, "four"),
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
@@ -54,6 +56,7 @@ int main()
P(2, "four"),
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp
new file mode 100644
index 000000000000..2d5e1843fd2f
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// template <class H2, class P2>
+// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>&& source);
+// template <class H2, class P2>
+// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>&& source);
+
+#include <unordered_map>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Map>
+bool map_equal(const Map& map, Map other)
+{
+ return map == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <class T>
+struct throw_hasher
+{
+ bool& should_throw_;
+
+ throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
+
+ size_t operator()(const T& p) const
+ {
+ if (should_throw_)
+ throw 0;
+ return std::hash<T>()(p);
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::unordered_map<int, int> src{{1, 0}, {3, 0}, {5, 0}};
+ std::unordered_map<int, int> dst{{2, 0}, {4, 0}, {5, 0}};
+ dst.merge(src);
+ assert(map_equal(src, {{5,0}}));
+ assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::unordered_map<Counter<int>, int, throw_hasher<Counter<int>>> map_type;
+ map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw));
+ map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw))));
+ assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct equal
+ {
+ equal() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs == rhs;
+ }
+ };
+ struct hasher
+ {
+ hasher() = default;
+ size_t operator()(const Counter<int>& p) const
+ {
+ return std::hash<Counter<int>>()(p);
+ }
+ };
+ {
+ typedef std::unordered_map<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type;
+ typedef std::unordered_map<Counter<int>, int, hasher, equal> second_map_type;
+ typedef std::unordered_multimap<Counter<int>, int, hasher, equal> third_map_type;
+
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {{2, 0}, {3, 0}}));
+ assert(map_equal(third, {{1, 0}, {3, 0}}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
+ assert(map_equal(second, {{2, 0}, {3, 0}}));
+ assert(map_equal(third, {{1, 0}, {3, 0}}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::unordered_map<int, int> first;
+ {
+ std::unordered_map<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::unordered_multimap<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp
index 382ed7c9831d..65c9f8c12134 100644
--- a/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/equal_range_const.pass.cpp
@@ -17,6 +17,7 @@
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include "min_allocator.h"
@@ -48,14 +49,17 @@ int main()
r = c.equal_range(5);
assert(std::distance(r.first, r.second) == 0);
r = c.equal_range(50);
- assert(r.first->first == 50);
- assert(r.first->second == "fifty");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyA");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyB");
+ std::set<std::string> s;
+ s.insert("fifty");
+ s.insert("fiftyA");
+ s.insert("fiftyB");
+ for ( int i = 0; i < 3; ++i )
+ {
+ assert(r.first->first == 50);
+ assert(s.find(r.first->second) != s.end());
+ s.erase(s.find(r.first->second));
+ ++r.first;
+ }
}
#if TEST_STD_VER >= 11
{
@@ -84,14 +88,17 @@ int main()
r = c.equal_range(5);
assert(std::distance(r.first, r.second) == 0);
r = c.equal_range(50);
- assert(r.first->first == 50);
- assert(r.first->second == "fifty");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyA");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyB");
+ std::set<std::string> s;
+ s.insert("fifty");
+ s.insert("fiftyA");
+ s.insert("fiftyB");
+ for ( int i = 0; i < 3; ++i )
+ {
+ assert(r.first->first == 50);
+ assert(s.find(r.first->second) != s.end());
+ s.erase(s.find(r.first->second));
+ ++r.first;
+ }
}
#endif
}
diff --git a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
index 17eb14e44262..10fafee8028f 100644
--- a/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
@@ -17,6 +17,7 @@
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include "min_allocator.h"
@@ -48,14 +49,17 @@ int main()
r = c.equal_range(5);
assert(std::distance(r.first, r.second) == 0);
r = c.equal_range(50);
- assert(r.first->first == 50);
- assert(r.first->second == "fifty");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyA");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyB");
+ std::set<std::string> s;
+ s.insert("fifty");
+ s.insert("fiftyA");
+ s.insert("fiftyB");
+ for ( int i = 0; i < 3; ++i )
+ {
+ assert(r.first->first == 50);
+ assert(s.find(r.first->second) != s.end());
+ s.erase(s.find(r.first->second));
+ ++r.first;
+ }
}
#if TEST_STD_VER >= 11
{
@@ -84,14 +88,17 @@ int main()
r = c.equal_range(5);
assert(std::distance(r.first, r.second) == 0);
r = c.equal_range(50);
- assert(r.first->first == 50);
- assert(r.first->second == "fifty");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyA");
- ++r.first;
- assert(r.first->first == 50);
- assert(r.first->second == "fiftyB");
+ std::set<std::string> s;
+ s.insert("fifty");
+ s.insert("fiftyA");
+ s.insert("fiftyB");
+ for ( int i = 0; i < 3; ++i )
+ {
+ assert(r.first->first == 50);
+ assert(s.find(r.first->second) != s.end());
+ s.erase(s.find(r.first->second));
+ ++r.first;
+ }
}
#endif
}
diff --git a/test/std/containers/unord/unord.multimap/erase_if.pass.cpp b/test/std/containers/unord/unord.multimap/erase_if.pass.cpp
new file mode 100644
index 000000000000..dc613269a353
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/erase_if.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash, class Pred, class Allocator, class Predicate>
+// void erase_if(unordered_multimap<Key, T, Hash, Pred, Allocator>& c, Predicate pred);
+
+#include <unordered_map>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret.insert(typename M::value_type(v, v + 10));
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ M e = make<M>(expected);
+ assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end())));
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v.first == 1;};
+ auto is2 = [](auto v) { return v.first == 2;};
+ auto is3 = [](auto v) { return v.first == 3;};
+ auto is4 = [](auto v) { return v.first == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+ test0<S>({1,1}, is1, {});
+ test0<S>({1,1}, is3, {1,1});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,1,1}, is1, {});
+ test0<S>({1,1,1}, is2, {1,1,1});
+ test0<S>({1,1,2}, is1, {2});
+ test0<S>({1,1,2}, is2, {1,1});
+ test0<S>({1,1,2}, is3, {1,1,2});
+ test0<S>({1,2,2}, is1, {2,2});
+ test0<S>({1,2,2}, is2, {1});
+ test0<S>({1,2,2}, is3, {1,2,2});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::unordered_multimap<int, int>>();
+ test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, int>>>> ();
+ test<std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, test_allocator<std::pair<const int, int>>>> ();
+
+ test<std::unordered_multimap<long, short>>();
+ test<std::unordered_multimap<short, double>>();
+}
diff --git a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp
index 504fe54de830..2976d2c3c8c1 100644
--- a/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/local_iterators.pass.cpp
@@ -22,6 +22,7 @@
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include "min_allocator.h"
@@ -52,21 +53,35 @@ int main()
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.begin(b);
@@ -116,21 +131,35 @@ int main()
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.begin(b);
@@ -180,21 +209,35 @@ int main()
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.cbegin(b);
@@ -244,21 +287,35 @@ int main()
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.cbegin(b);
@@ -310,21 +367,35 @@ int main()
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.begin(b);
@@ -375,21 +446,35 @@ int main()
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.begin(b);
j = c.end(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.begin(b);
@@ -440,21 +525,35 @@ int main()
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.cbegin(b);
@@ -505,21 +604,35 @@ int main()
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(2);
i = c.cbegin(b);
j = c.cend(b);
assert(std::distance(i, j) == 2);
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
b = c.bucket(3);
i = c.cbegin(b);
diff --git a/test/std/containers/unord/unord.multimap/max_size.pass.cpp b/test/std/containers/unord/unord.multimap/max_size.pass.cpp
index 5b58bac385a4..228575c2eff8 100644
--- a/test/std/containers/unord/unord.multimap/max_size.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/max_size.pass.cpp
@@ -38,16 +38,16 @@ int main()
typedef std::unordered_multimap<int, int, std::hash<int>,
std::equal_to<int>, A>
C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::unordered_multimap<char, int> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/unord/unord.multimap/rehash.pass.cpp b/test/std/containers/unord/unord.multimap/rehash.pass.cpp
index 22202ccb612a..e8394d7f752d 100644
--- a/test/std/containers/unord/unord.multimap/rehash.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/rehash.pass.cpp
@@ -17,6 +17,7 @@
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include <cfloat>
#include <cmath>
@@ -39,20 +40,33 @@ void test(const C& c)
Eq eq = c.equal_range(1);
assert(std::distance(eq.first, eq.second) == 2);
typename C::const_iterator i = eq.first;
- assert(i->first == 1);
- assert(i->second == "one");
- ++i;
- assert(i->first == 1);
- assert(i->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 1);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
eq = c.equal_range(2);
assert(std::distance(eq.first, eq.second) == 2);
i = eq.first;
- assert(i->first == 2);
- assert(i->second == "two");
- ++i;
- assert(i->first == 2);
- assert(i->second == "four");
-
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ for ( int n = 0; n < 2; ++n )
+ {
+ assert(i->first == 2);
+ assert(s.find(i->second) != s.end());
+ s.erase(s.find(i->second));
+ ++i;
+ }
+ }
eq = c.equal_range(3);
assert(std::distance(eq.first, eq.second) == 1);
i = eq.first;
diff --git a/test/std/containers/unord/unord.multimap/reserve.pass.cpp b/test/std/containers/unord/unord.multimap/reserve.pass.cpp
index d86c69c88f25..0033377741d7 100644
--- a/test/std/containers/unord/unord.multimap/reserve.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/reserve.pass.cpp
@@ -13,10 +13,11 @@
// class Alloc = allocator<pair<const Key, T>>>
// class unordered_multimap
-// void rehash(size_type n);
+// void reserve(size_type n);
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include "test_macros.h"
@@ -26,10 +27,22 @@ template <class C>
void test(const C& c)
{
assert(c.size() == 6);
- assert(c.find(1)->second == "one");
- assert(next(c.find(1))->second == "four");
- assert(c.find(2)->second == "two");
- assert(next(c.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c.find(1)->second) != s.end());
+ s.erase(s.find(c.find(1)->second));
+ assert(s.find(next(c.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c.find(2)->second) != s.end());
+ s.erase(s.find(c.find(2)->second));
+ assert(s.find(next(c.find(2))->second) != s.end());
+ }
assert(c.find(3)->second == "three");
assert(c.find(4)->second == "four");
}
diff --git a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp
index 8c5ddab054e5..3f0259794ffb 100644
--- a/test/std/containers/unord/unord.multimap/swap_member.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/swap_member.pass.cpp
@@ -17,6 +17,7 @@
#include <unordered_map>
#include <string>
+#include <set>
#include <cassert>
#include <cstddef>
@@ -136,10 +137,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
@@ -199,10 +212,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
@@ -320,10 +345,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
@@ -383,10 +420,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
@@ -504,10 +553,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
@@ -567,10 +628,22 @@ int main()
assert(c2.bucket_count() >= 6);
assert(c2.size() == 6);
- assert(c2.find(1)->second == "one");
- assert(next(c2.find(1))->second == "four");
- assert(c2.find(2)->second == "two");
- assert(next(c2.find(2))->second == "four");
+ {
+ std::set<std::string> s;
+ s.insert("one");
+ s.insert("four");
+ assert(s.find(c2.find(1)->second) != s.end());
+ s.erase(s.find(c2.find(1)->second));
+ assert(s.find(next(c2.find(1))->second) != s.end());
+ }
+ {
+ std::set<std::string> s;
+ s.insert("two");
+ s.insert("four");
+ assert(s.find(c2.find(2)->second) != s.end());
+ s.erase(s.find(c2.find(2)->second));
+ assert(s.find(next(c2.find(2))->second) != s.end());
+ }
assert(c2.find(3)->second == "three");
assert(c2.find(4)->second == "four");
assert(c2.hash_function() == Hash(1));
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
index 62e756cda3b1..d5729e350dc3 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
@@ -19,6 +19,8 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
+#include <algorithm>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
index cefbf4596550..f06ed700fb46 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "../../../test_compare.h"
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
index 9bd55ac92e89..11a1759bbc45 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
index 1a222cef1509..b3519fd5056d 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
index 11465edae3e5..7baf11f52c04 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
@@ -20,6 +20,7 @@
#include <string>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
index 891d44911eb0..15c78208a616 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
@@ -13,12 +13,13 @@
// class Alloc = allocator<pair<const Key, T>>>
// class unordered_multimap
-// void clear()
+// void clear() noexcept;
#include <unordered_map>
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -36,6 +37,7 @@ int main()
P(2, "four"),
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
@@ -54,6 +56,7 @@ int main()
P(2, "four"),
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp
new file mode 100644
index 000000000000..b7f61ca5adc2
--- /dev/null
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_multimap
+
+// template <class H2, class P2>
+// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>&& source);
+// template <class H2, class P2>
+// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>&& source);
+
+#include <unordered_map>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Map>
+bool map_equal(const Map& map, Map other)
+{
+ return map == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <class T>
+struct throw_hasher
+{
+ bool& should_throw_;
+
+ throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
+
+ size_t operator()(const T& p) const
+ {
+ if (should_throw_)
+ throw 0;
+ return std::hash<T>()(p);
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::unordered_multimap<int, int> src{{1, 0}, {3, 0}, {5, 0}};
+ std::unordered_multimap<int, int> dst{{2, 0}, {4, 0}, {5, 0}};
+ dst.merge(src);
+ assert(map_equal(src, {}));
+ assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {5, 0}}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::unordered_multimap<Counter<int>, int, throw_hasher<Counter<int>>> map_type;
+ map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw));
+ map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw))));
+ assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct equal
+ {
+ equal() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs == rhs;
+ }
+ };
+ struct hasher
+ {
+ hasher() = default;
+ size_t operator()(const Counter<int>& p) const
+ {
+ return std::hash<Counter<int>>()(p);
+ }
+ };
+ {
+ typedef std::unordered_multimap<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type;
+ typedef std::unordered_multimap<Counter<int>, int, hasher, equal> second_map_type;
+ typedef std::unordered_map<Counter<int>, int, hasher, equal> third_map_type;
+
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {2, 0}, {3, 0}, {1, 0}, {3, 0}}));
+ assert(map_equal(second, {}));
+ assert(map_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_map_type first{{1, 0}, {2, 0}, {3, 0}};
+ second_map_type second{{2, 0}, {3, 0}, {4, 0}};
+ third_map_type third{{1, 0}, {3, 0}};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {2, 0}, {3, 0}, {1, 0}, {3, 0}}));
+ assert(map_equal(second, {}));
+ assert(map_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::unordered_multimap<int, int> first;
+ {
+ std::unordered_multimap<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::unordered_map<int, int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/unord/unord.multiset/clear.pass.cpp b/test/std/containers/unord/unord.multiset/clear.pass.cpp
index 57dbb8b1faaa..b699d0624ddd 100644
--- a/test/std/containers/unord/unord.multiset/clear.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/clear.pass.cpp
@@ -13,11 +13,12 @@
// class Alloc = allocator<Value>>
// class unordered_multiset
-// void clear()
+// void clear() noexcept;
#include <unordered_set>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -35,6 +36,7 @@ int main()
P(2)
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
@@ -53,6 +55,7 @@ int main()
P(2)
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
diff --git a/test/std/containers/unord/unord.multiset/erase_if.pass.cpp b/test/std/containers/unord/unord.multiset/erase_if.pass.cpp
new file mode 100644
index 000000000000..7a9d93d432f7
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/erase_if.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <set>
+
+// template <class T, class Hash, class Compare, class Allocator, class Predicate>
+// void erase_if(unordered_multiset<T, Hash, Compare, Allocator>& c, Predicate pred);
+
+#include <unordered_set>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret.insert(v);
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ M e = make<M>(expected);
+ assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end())));
+}
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+ test0<S>({1,1}, is1, {});
+ test0<S>({1,1}, is3, {1,1});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,1,1}, is1, {});
+ test0<S>({1,1,1}, is2, {1,1,1});
+ test0<S>({1,1,2}, is1, {2});
+ test0<S>({1,1,2}, is2, {1,1});
+ test0<S>({1,1,2}, is3, {1,1,2});
+ test0<S>({1,2,2}, is1, {2,2});
+ test0<S>({1,2,2}, is2, {1});
+ test0<S>({1,2,2}, is3, {1,2,2});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::unordered_multiset<int>>();
+ test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> ();
+ test<std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> ();
+
+ test<std::unordered_multiset<long>>();
+ test<std::unordered_multiset<double>>();
+}
diff --git a/test/std/containers/unord/unord.multiset/erase_range.pass.cpp b/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
index a4f703df8506..14eb7c477fd9 100644
--- a/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/erase_range.pass.cpp
@@ -17,6 +17,7 @@
#include <unordered_set>
#include <cassert>
+#include <iterator>
#include "min_allocator.h"
diff --git a/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.multiset/insert_emplace_allocator_requirements.pass.cpp
index ad7bc043a5b3..4b6e2f769720 100644
--- a/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/insert_emplace_allocator_requirements.pass.cpp
@@ -22,4 +22,5 @@
int main()
{
testMultisetInsert<TCT::unordered_multiset<> >();
+ testMultisetEmplace<TCT::unordered_multiset<> >();
}
diff --git a/test/std/containers/unord/unord.multiset/max_size.pass.cpp b/test/std/containers/unord/unord.multiset/max_size.pass.cpp
index eac4db8b0a91..e76624e5cd5f 100644
--- a/test/std/containers/unord/unord.multiset/max_size.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/max_size.pass.cpp
@@ -37,16 +37,16 @@ int main()
typedef std::unordered_multiset<int, std::hash<int>, std::equal_to<int>,
A>
C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::unordered_multiset<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/unord/unord.multiset/merge.pass.cpp b/test/std/containers/unord/unord.multiset/merge.pass.cpp
new file mode 100644
index 000000000000..7913f9564362
--- /dev/null
+++ b/test/std/containers/unord/unord.multiset/merge.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_multiset
+
+// template <class H2, class P2>
+// void merge(unordered_set<key_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_set<key_type, H2, P2, allocator_type>&& source);
+// template <class H2, class P2>
+// void merge(unordered_multiset<key_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source);
+
+#include <unordered_set>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Set>
+bool set_equal(const Set& set, Set other)
+{
+ return set == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <class T>
+struct throw_hasher
+{
+ bool& should_throw_;
+
+ throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
+
+ size_t operator()(const T& p) const
+ {
+ if (should_throw_)
+ throw 0;
+ return std::hash<T>()(p);
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::unordered_multiset<int> src{1, 3, 5};
+ std::unordered_multiset<int> dst{2, 4, 5};
+ dst.merge(src);
+ assert(set_equal(src, {}));
+ assert(set_equal(dst, {1, 2, 3, 4, 5, 5}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::unordered_multiset<Counter<int>, throw_hasher<Counter<int>>> set_type;
+ set_type src({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw));
+ set_type dst({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(set_equal(src, set_type({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw))));
+ assert(set_equal(dst, set_type({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct equal
+ {
+ equal() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs == rhs;
+ }
+ };
+ struct hasher
+ {
+ hasher() = default;
+ size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); }
+ };
+ {
+ typedef std::unordered_multiset<Counter<int>, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_set_type;
+ typedef std::unordered_multiset<Counter<int>, hasher, equal> second_set_type;
+ typedef std::unordered_set<Counter<int>, hasher, equal> third_set_type;
+
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(set_equal(first, {1, 2, 3, 4, 2, 3, 1, 3}));
+ assert(set_equal(second, {}));
+ assert(set_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(set_equal(first, {1, 2, 3, 4, 2, 3, 1, 3}));
+ assert(set_equal(second, {}));
+ assert(set_equal(third, {}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::unordered_multiset<int> first;
+ {
+ std::unordered_multiset<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::unordered_set<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
index b7557c437181..e1794c0d8955 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
@@ -16,8 +16,10 @@
// unordered_multiset& operator=(const unordered_multiset& u);
#include <unordered_set>
+#include <algorithm>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
index ce664034d1e1..5ab0209ce646 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "../../../test_compare.h"
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
index dfcb63e6e0eb..17ac618fabc5 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
index df49abe077ca..d98b9a7d0399 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
index a2ee746791d3..fd3b76316f49 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
@@ -19,6 +19,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.set/clear.pass.cpp b/test/std/containers/unord/unord.set/clear.pass.cpp
index 8ebf748eb8da..2f22391297c4 100644
--- a/test/std/containers/unord/unord.set/clear.pass.cpp
+++ b/test/std/containers/unord/unord.set/clear.pass.cpp
@@ -13,11 +13,12 @@
// class Alloc = allocator<Value>>
// class unordered_set
-// void clear()
+// void clear() noexcept;
#include <unordered_set>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -35,6 +36,7 @@ int main()
P(2)
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
@@ -52,6 +54,7 @@ int main()
P(2)
};
C c(a, a + sizeof(a)/sizeof(a[0]));
+ ASSERT_NOEXCEPT(c.clear());
c.clear();
assert(c.size() == 0);
}
diff --git a/test/std/containers/unord/unord.set/erase_if.pass.cpp b/test/std/containers/unord/unord.set/erase_if.pass.cpp
new file mode 100644
index 000000000000..e060fda1fe8c
--- /dev/null
+++ b/test/std/containers/unord/unord.set/erase_if.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <unordered_set>
+
+// template <class T, class Hash, class Compare, class Allocator, class Predicate>
+// void erase_if(unorderd_set<T, Hash, Compare, Allocator>& c, Predicate pred);
+
+#include <unordered_set>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+using Init = std::initializer_list<int>;
+
+template <typename M>
+M make (Init vals)
+{
+ M ret;
+ for (int v : vals)
+ ret.insert(v);
+ return ret;
+}
+
+template <typename M, typename Pred>
+void
+test0(Init vals, Pred p, Init expected)
+{
+ M s = make<M> (vals);
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ M e = make<M>(expected);
+ assert((std::is_permutation(s.begin(), s.end(), e.begin(), e.end())));
+}
+
+
+template <typename S>
+void test()
+{
+ auto is1 = [](auto v) { return v == 1;};
+ auto is2 = [](auto v) { return v == 2;};
+ auto is3 = [](auto v) { return v == 3;};
+ auto is4 = [](auto v) { return v == 4;};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0<S>({}, is1, {});
+
+ test0<S>({1}, is1, {});
+ test0<S>({1}, is2, {1});
+
+ test0<S>({1,2}, is1, {2});
+ test0<S>({1,2}, is2, {1});
+ test0<S>({1,2}, is3, {1,2});
+
+ test0<S>({1,2,3}, is1, {2,3});
+ test0<S>({1,2,3}, is2, {1,3});
+ test0<S>({1,2,3}, is3, {1,2});
+ test0<S>({1,2,3}, is4, {1,2,3});
+
+ test0<S>({1,2,3}, True, {});
+ test0<S>({1,2,3}, False, {1,2,3});
+}
+
+int main()
+{
+ test<std::unordered_set<int>>();
+ test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>>> ();
+ test<std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>> ();
+
+ test<std::unordered_set<long>>();
+ test<std::unordered_set<double>>();
+}
diff --git a/test/std/containers/unord/unord.set/erase_range.pass.cpp b/test/std/containers/unord/unord.set/erase_range.pass.cpp
index 4e49a86ef836..ca8250c1e594 100644
--- a/test/std/containers/unord/unord.set/erase_range.pass.cpp
+++ b/test/std/containers/unord/unord.set/erase_range.pass.cpp
@@ -16,6 +16,7 @@
// iterator erase(const_iterator first, const_iterator last)
#include <unordered_set>
+#include <algorithm>
#include <cassert>
#include "min_allocator.h"
diff --git a/test/std/containers/unord/unord.set/max_size.pass.cpp b/test/std/containers/unord/unord.set/max_size.pass.cpp
index 1b902660d48f..eb695ae97281 100644
--- a/test/std/containers/unord/unord.set/max_size.pass.cpp
+++ b/test/std/containers/unord/unord.set/max_size.pass.cpp
@@ -33,16 +33,16 @@ int main()
{
typedef limited_allocator<int, (size_t)-1> A;
typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, A> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
LIBCPP_ASSERT(c.max_size() == max_dist);
}
{
typedef std::unordered_set<char> C;
- const C::difference_type max_dist =
- std::numeric_limits<C::difference_type>::max();
+ const C::size_type max_dist =
+ static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
C c;
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_allocator()));
diff --git a/test/std/containers/unord/unord.set/merge.pass.cpp b/test/std/containers/unord/unord.set/merge.pass.cpp
new file mode 100644
index 000000000000..519d7f138549
--- /dev/null
+++ b/test/std/containers/unord/unord.set/merge.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_set>
+
+// class unordered_set
+
+// template <class H2, class P2>
+// void merge(unordered_set<key_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_set<key_type, H2, P2, allocator_type>&& source);
+// template <class H2, class P2>
+// void merge(unordered_multiset<key_type, H2, P2, allocator_type>& source);
+// template <class H2, class P2>
+// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source);
+
+#include <unordered_set>
+#include <cassert>
+#include "test_macros.h"
+#include "Counter.h"
+
+template <class Set>
+bool set_equal(const Set& set, Set other)
+{
+ return set == other;
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <class T>
+struct throw_hasher
+{
+ bool& should_throw_;
+
+ throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
+
+ size_t operator()(const T& p) const
+ {
+ if (should_throw_)
+ throw 0;
+ return std::hash<T>()(p);
+ }
+};
+#endif
+
+int main()
+{
+ {
+ std::unordered_set<int> src{1, 3, 5};
+ std::unordered_set<int> dst{2, 4, 5};
+ dst.merge(src);
+ assert(set_equal(src, {5}));
+ assert(set_equal(dst, {1, 2, 3, 4, 5}));
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool do_throw = false;
+ typedef std::unordered_set<Counter<int>, throw_hasher<Counter<int>>> set_type;
+ set_type src({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw));
+ set_type dst({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw));
+
+ assert(Counter_base::gConstructed == 6);
+
+ do_throw = true;
+ try
+ {
+ dst.merge(src);
+ }
+ catch (int)
+ {
+ do_throw = false;
+ }
+ assert(!do_throw);
+ assert(set_equal(src, set_type({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw))));
+ assert(set_equal(dst, set_type({2, 4, 5}, 0, throw_hasher<Counter<int>>(do_throw))));
+ }
+#endif
+ assert(Counter_base::gConstructed == 0);
+ struct equal
+ {
+ equal() = default;
+
+ bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
+ {
+ return lhs == rhs;
+ }
+ };
+ struct hasher
+ {
+ hasher() = default;
+ size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); }
+ };
+ {
+ typedef std::unordered_set<Counter<int>, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_set_type;
+ typedef std::unordered_set<Counter<int>, hasher, equal> second_set_type;
+ typedef std::unordered_multiset<Counter<int>, hasher, equal> third_set_type;
+
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(second);
+ first.merge(third);
+
+ assert(set_equal(first, {1, 2, 3, 4}));
+ assert(set_equal(second, {2, 3}));
+ assert(set_equal(third, {1, 3}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ {
+ first_set_type first{1, 2, 3};
+ second_set_type second{2, 3, 4};
+ third_set_type third{1, 3};
+
+ assert(Counter_base::gConstructed == 8);
+
+ first.merge(std::move(second));
+ first.merge(std::move(third));
+
+ assert(set_equal(first, {1, 2, 3, 4}));
+ assert(set_equal(second, {2, 3}));
+ assert(set_equal(third, {1, 3}));
+
+ assert(Counter_base::gConstructed == 8);
+ }
+ assert(Counter_base::gConstructed == 0);
+ }
+ {
+ std::unordered_set<int> first;
+ {
+ std::unordered_set<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ {
+ std::unordered_multiset<int> second;
+ first.merge(second);
+ first.merge(std::move(second));
+ }
+ }
+}
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp
index 0859d8edc85e..cf473a930fb4 100644
--- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp
@@ -16,8 +16,10 @@
// unordered_set& operator=(const unordered_set& u);
#include <unordered_set>
+#include <algorithm>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp
index 4f7ccfec652e..4e0f68c71670 100644
--- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_init.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "../../../test_compare.h"
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp
index bc3658243995..f89c45caf787 100644
--- a/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp
index 7ba340bf9c3e..ff46e08f48f7 100644
--- a/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.cnstr/init.pass.cpp
@@ -20,6 +20,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp b/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp
index 5bcc288aacbd..b6ad0e2a189b 100644
--- a/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.cnstr/range.pass.cpp
@@ -19,6 +19,7 @@
#include <unordered_set>
#include <cassert>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include "test_macros.h"
diff --git a/test/std/containers/views/span.comparison/op.eq.pass.cpp b/test/std/containers/views/span.comparison/op.eq.pass.cpp
deleted file mode 100644
index 963054580466..000000000000
--- a/test/std/containers/views/span.comparison/op.eq.pass.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator==(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to: return equal(l.begin(), l.end(), r.begin(), r.end());
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert( (csp0d == csp0d), "");
- static_assert( (csp0s == csp0s), "");
- static_assert( (csp0s == csp0d), "");
- static_assert( (csp0d == csp0s), "");
-
- static_assert(!(csp0d == csp1d), "");
- static_assert(!(csp0s == csp1s), "");
- static_assert(!(csp0s == csp1d), "");
- static_assert(!(csp0d == csp1s), "");
-
- static_assert( (csp1d == csp1s), "");
- static_assert( (csp1s == csp1d), "");
-
- static_assert( (csp2d == csp3d), "");
- static_assert( (csp2s == csp3s), "");
- static_assert( (csp2d == csp3s), "");
- static_assert( (csp2s == csp3d), "");
-
- static_assert( (csp2d == csp3d), "");
- static_assert( (csp2s == csp3s), "");
- static_assert( (csp2d == csp3s), "");
- static_assert( (csp2s == csp3d), "");
-
- static_assert(!(csp2d == csp4d), "");
- static_assert(!(csp2s == csp4s), "");
- static_assert(!(csp2d == csp4s), "");
- static_assert(!(csp2s == csp4d), "");
-
- static_assert(!(csp4d == csp2d), "");
- static_assert(!(csp4s == csp2s), "");
- static_assert(!(csp4d == csp2s), "");
- static_assert(!(csp4s == csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert( (sp0d == sp0d));
- assert( (sp0s == sp0s));
- assert( (sp0s == sp0d));
- assert( (sp0d == sp0s));
-
- assert(!(sp0d == sp1d));
- assert(!(sp0s == sp1s));
- assert(!(sp0s == sp1d));
- assert(!(sp0d == sp1s));
-
- assert( (sp1d == sp1s));
- assert( (sp1s == sp1d));
-
- assert( (sp2d == sp3d));
- assert( (sp2s == sp3s));
- assert( (sp2d == sp3s));
- assert( (sp2s == sp3d));
-
- assert( (sp2d == sp3d));
- assert( (sp2s == sp3s));
- assert( (sp2d == sp3s));
- assert( (sp2s == sp3d));
-
- assert(!(sp2d == sp4d));
- assert(!(sp2s == sp4s));
- assert(!(sp2d == sp4s));
- assert(!(sp2s == sp4d));
-
- assert(!(sp4d == sp2d));
- assert(!(sp4s == sp2s));
- assert(!(sp4d == sp2s));
- assert(!(sp4s == sp2d));
-
-// cross type comparisons
- assert( (csp0d == sp0d));
- assert( (csp0s == sp0s));
- assert( (csp0s == sp0d));
- assert( (csp0d == sp0s));
-
- assert(!(csp0d == sp1d));
- assert(!(csp0s == sp1s));
- assert(!(csp0s == sp1d));
- assert(!(csp0d == sp1s));
-
- assert( (csp1d == sp1s));
- assert( (csp1s == sp1d));
-
- assert( (csp2d == sp3d));
- assert( (csp2s == sp3s));
- assert( (csp2d == sp3s));
- assert( (csp2s == sp3d));
-
- assert( (csp2d == sp3d));
- assert( (csp2s == sp3s));
- assert( (csp2d == sp3s));
- assert( (csp2s == sp3d));
-
- assert(!(csp2d == sp4d));
- assert(!(csp2s == sp4s));
- assert(!(csp2d == sp4s));
- assert(!(csp2s == sp4d));
-
- assert(!(csp4d == sp2d));
- assert(!(csp4s == sp2s));
- assert(!(csp4d == sp2s));
- assert(!(csp4s == sp2d));
-
-// More cross-type comparisons (int vs float)
- static_assert(std::span<const float>{fArr1} == std::span<const int>{iArr1}, "");
- static_assert(std::span<const int>{iArr1} == std::span<const float>{fArr1}, "");
- assert(std::span<float>{fArr2} == std::span<int>{iArr2});
- assert(std::span<int>{iArr2} == std::span<float>{fArr2});
-
- static_assert(!(std::span<const int>{iArr1, 9} == std::span<const float>{fArr1, 8}), "");
-} \ No newline at end of file
diff --git a/test/std/containers/views/span.comparison/op.ge.pass.cpp b/test/std/containers/views/span.comparison/op.ge.pass.cpp
deleted file mode 100644
index 8ec1b9a590eb..000000000000
--- a/test/std/containers/views/span.comparison/op.ge.pass.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator>=(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to: return !(l < r);
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert( (csp0d >= csp0d), "");
- static_assert( (csp0s >= csp0s), "");
- static_assert( (csp0s >= csp0d), "");
- static_assert( (csp0d >= csp0s), "");
-
- static_assert(!(csp0d >= csp1d), "");
- static_assert(!(csp0s >= csp1s), "");
- static_assert(!(csp0s >= csp1d), "");
- static_assert(!(csp0d >= csp1s), "");
-
- static_assert( (csp1d >= csp1s), "");
- static_assert( (csp1s >= csp1d), "");
-
- static_assert( (csp2d >= csp3d), "");
- static_assert( (csp2s >= csp3s), "");
- static_assert( (csp2d >= csp3s), "");
- static_assert( (csp2s >= csp3d), "");
-
- static_assert(!(csp2d >= csp4d), "");
- static_assert(!(csp2s >= csp4s), "");
- static_assert(!(csp2d >= csp4s), "");
- static_assert(!(csp2s >= csp4d), "");
-
- static_assert( (csp4d >= csp2d), "");
- static_assert( (csp4s >= csp2s), "");
- static_assert( (csp4d >= csp2s), "");
- static_assert( (csp4s >= csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert( (sp0d >= sp0d));
- assert( (sp0s >= sp0s));
- assert( (sp0s >= sp0d));
- assert( (sp0d >= sp0s));
-
- assert(!(sp0d >= sp1d));
- assert(!(sp0s >= sp1s));
- assert(!(sp0s >= sp1d));
- assert(!(sp0d >= sp1s));
-
- assert( (sp1d >= sp1s));
- assert( (sp1s >= sp1d));
-
- assert( (sp2d >= sp3d));
- assert( (sp2s >= sp3s));
- assert( (sp2d >= sp3s));
- assert( (sp2s >= sp3d));
-
- assert(!(sp2d >= sp4d));
- assert(!(sp2s >= sp4s));
- assert(!(sp2d >= sp4s));
- assert(!(sp2s >= sp4d));
-
- assert( (sp4d > sp2d));
- assert( (sp4s > sp2s));
- assert( (sp4d > sp2s));
- assert( (sp4s > sp2d));
-
-// cross type comparisons
- assert( (csp0d >= sp0d));
- assert( (csp0s >= sp0s));
- assert( (csp0s >= sp0d));
- assert( (csp0d >= sp0s));
-
- assert(!(csp0d >= sp1d));
- assert(!(csp0s >= sp1s));
- assert(!(csp0s >= sp1d));
- assert(!(csp0d >= sp1s));
-
- assert( (csp1d >= sp1s));
- assert( (csp1s >= sp1d));
-
- assert( (csp2d >= sp3d));
- assert( (csp2s >= sp3s));
- assert( (csp2d >= sp3s));
- assert( (csp2s >= sp3d));
-
- assert(!(csp2d >= sp4d));
- assert(!(csp2s >= sp4s));
- assert(!(csp2d >= sp4s));
- assert(!(csp2s >= sp4d));
-
- assert( (csp4d > sp2d));
- assert( (csp4s > sp2s));
- assert( (csp4d > sp2s));
- assert( (csp4s > sp2d));
-
-// More cross-type comparisons (int vs float)
- static_assert(!(std::span<const float>{fArr1, 8} >= std::span<const int>{iArr1, 9}), "");
- static_assert(!(std::span<const int>{iArr1, 8} >= std::span<const float>{fArr1, 9}), "");
- assert( (std::span<float>{fArr2} >= std::span<int>{iArr2}));
- assert( (std::span<int>{iArr2} >= std::span<float>{fArr2}));
-
- static_assert( (std::span<const int>{iArr1, 9} >= std::span<const float>{fArr1, 8}), "");
-}
diff --git a/test/std/containers/views/span.comparison/op.gt.pass.cpp b/test/std/containers/views/span.comparison/op.gt.pass.cpp
deleted file mode 100644
index 345a291a62b3..000000000000
--- a/test/std/containers/views/span.comparison/op.gt.pass.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator>(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to: return (r < l);
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert(!(csp0d > csp0d), "");
- static_assert(!(csp0s > csp0s), "");
- static_assert(!(csp0s > csp0d), "");
- static_assert(!(csp0d > csp0s), "");
-
- static_assert(!(csp0d > csp1d), "");
- static_assert(!(csp0s > csp1s), "");
- static_assert(!(csp0s > csp1d), "");
- static_assert(!(csp0d > csp1s), "");
-
- static_assert(!(csp1d > csp1s), "");
- static_assert(!(csp1s > csp1d), "");
-
- static_assert(!(csp2d > csp3d), "");
- static_assert(!(csp2s > csp3s), "");
- static_assert(!(csp2d > csp3s), "");
- static_assert(!(csp2s > csp3d), "");
-
- static_assert(!(csp2d > csp4d), "");
- static_assert(!(csp2s > csp4s), "");
- static_assert(!(csp2d > csp4s), "");
- static_assert(!(csp2s > csp4d), "");
-
- static_assert( (csp4d > csp2d), "");
- static_assert( (csp4s > csp2s), "");
- static_assert( (csp4d > csp2s), "");
- static_assert( (csp4s > csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert(!(sp0d > sp0d));
- assert(!(sp0s > sp0s));
- assert(!(sp0s > sp0d));
- assert(!(sp0d > sp0s));
-
- assert(!(sp0d > sp1d));
- assert(!(sp0s > sp1s));
- assert(!(sp0s > sp1d));
- assert(!(sp0d > sp1s));
-
- assert(!(sp1d > sp1s));
- assert(!(sp1s > sp1d));
-
- assert(!(sp2d > sp3d));
- assert(!(sp2s > sp3s));
- assert(!(sp2d > sp3s));
- assert(!(sp2s > sp3d));
-
- assert(!(sp2d > sp4d));
- assert(!(sp2s > sp4s));
- assert(!(sp2d > sp4s));
- assert(!(sp2s > sp4d));
-
- assert( (sp4d > sp2d));
- assert( (sp4s > sp2s));
- assert( (sp4d > sp2s));
- assert( (sp4s > sp2d));
-
-// cross type comparisons
- assert(!(csp0d > sp0d));
- assert(!(csp0s > sp0s));
- assert(!(csp0s > sp0d));
- assert(!(csp0d > sp0s));
-
- assert(!(csp0d > sp1d));
- assert(!(csp0s > sp1s));
- assert(!(csp0s > sp1d));
- assert(!(csp0d > sp1s));
-
- assert(!(csp1d > sp1s));
- assert(!(csp1s > sp1d));
-
- assert(!(csp2d > sp3d));
- assert(!(csp2s > sp3s));
- assert(!(csp2d > sp3s));
- assert(!(csp2s > sp3d));
-
- assert(!(csp2d > sp4d));
- assert(!(csp2s > sp4s));
- assert(!(csp2d > sp4s));
- assert(!(csp2s > sp4d));
-
- assert( (csp4d > sp2d));
- assert( (csp4s > sp2s));
- assert( (csp4d > sp2s));
- assert( (csp4s > sp2d));
-
-
-// More cross-type comparisons (int vs float)
- static_assert(!(std::span<const float>{fArr1, 8} > std::span<const int>{iArr1, 9}), "");
- static_assert(!(std::span<const int>{iArr1, 8} > std::span<const float>{fArr1, 9}), "");
- assert(!(std::span<float>{fArr2} > std::span<int>{iArr2}));
- assert(!(std::span<int>{iArr2} > std::span<float>{fArr2}));
-
- static_assert( (std::span<const int>{iArr1, 9} > std::span<const float>{fArr1, 8}), "");
-} \ No newline at end of file
diff --git a/test/std/containers/views/span.comparison/op.le.pass.cpp b/test/std/containers/views/span.comparison/op.le.pass.cpp
deleted file mode 100644
index f2fbc8609082..000000000000
--- a/test/std/containers/views/span.comparison/op.le.pass.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator<=(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to: return !(r < l);
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert( (csp0d <= csp0d), "");
- static_assert( (csp0s <= csp0s), "");
- static_assert( (csp0s <= csp0d), "");
- static_assert( (csp0d <= csp0s), "");
-
- static_assert( (csp0d <= csp1d), "");
- static_assert( (csp0s <= csp1s), "");
- static_assert( (csp0s <= csp1d), "");
- static_assert( (csp0d <= csp1s), "");
-
- static_assert( (csp1d <= csp1s), "");
- static_assert( (csp1s <= csp1d), "");
-
- static_assert( (csp2d <= csp3d), "");
- static_assert( (csp2s <= csp3s), "");
- static_assert( (csp2d <= csp3s), "");
- static_assert( (csp2s <= csp3d), "");
-
- static_assert( (csp2d <= csp4d), "");
- static_assert( (csp2s <= csp4s), "");
- static_assert( (csp2d <= csp4s), "");
- static_assert( (csp2s <= csp4d), "");
-
- static_assert(!(csp4d <= csp2d), "");
- static_assert(!(csp4s <= csp2s), "");
- static_assert(!(csp4d <= csp2s), "");
- static_assert(!(csp4s <= csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert( (sp0d <= sp0d));
- assert( (sp0s <= sp0s));
- assert( (sp0s <= sp0d));
- assert( (sp0d <= sp0s));
-
- assert( (sp0d <= sp1d));
- assert( (sp0s <= sp1s));
- assert( (sp0s <= sp1d));
- assert( (sp0d <= sp1s));
-
- assert( (sp1d <= sp1s));
- assert( (sp1s <= sp1d));
-
- assert( (sp2d <= sp3d));
- assert( (sp2s <= sp3s));
- assert( (sp2d <= sp3s));
- assert( (sp2s <= sp3d));
-
- assert( (sp2d <= sp4d));
- assert( (sp2s <= sp4s));
- assert( (sp2d <= sp4s));
- assert( (sp2s <= sp4d));
-
- assert(!(sp4d <= sp2d));
- assert(!(sp4s <= sp2s));
- assert(!(sp4d <= sp2s));
- assert(!(sp4s <= sp2d));
-
-// cross type comparisons
- assert( (csp0d <= sp0d));
- assert( (csp0s <= sp0s));
- assert( (csp0s <= sp0d));
- assert( (csp0d <= sp0s));
-
- assert( (csp0d <= sp1d));
- assert( (csp0s <= sp1s));
- assert( (csp0s <= sp1d));
- assert( (csp0d <= sp1s));
-
- assert( (csp1d <= sp1s));
- assert( (csp1s <= sp1d));
-
- assert( (csp2d <= sp3d));
- assert( (csp2s <= sp3s));
- assert( (csp2d <= sp3s));
- assert( (csp2s <= sp3d));
-
- assert( (csp2d <= sp4d));
- assert( (csp2s <= sp4s));
- assert( (csp2d <= sp4s));
- assert( (csp2s <= sp4d));
-
- assert(!(csp4d <= sp2d));
- assert(!(csp4s <= sp2s));
- assert(!(csp4d <= sp2s));
- assert(!(csp4s <= sp2d));
-
-// More cross-type comparisons (int vs float)
- static_assert(std::span<const float>{fArr1, 8} <= std::span<const int>{iArr1, 9}, "");
- static_assert(std::span<const int>{iArr1, 8} <= std::span<const float>{fArr1, 9}, "");
- assert( (std::span<float>{fArr2} <= std::span<int>{iArr2}));
- assert( (std::span<int>{iArr2} <= std::span<float>{fArr2}));
-
- static_assert(!(std::span<const int>{iArr1, 9} <= std::span<const float>{fArr1, 8}), "");
-} \ No newline at end of file
diff --git a/test/std/containers/views/span.comparison/op.lt.pass.cpp b/test/std/containers/views/span.comparison/op.lt.pass.cpp
deleted file mode 100644
index 1a7de292e901..000000000000
--- a/test/std/containers/views/span.comparison/op.lt.pass.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator<(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to:
-// return lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert(!(csp0d < csp0d), "");
- static_assert(!(csp0s < csp0s), "");
- static_assert(!(csp0s < csp0d), "");
- static_assert(!(csp0d < csp0s), "");
-
- static_assert( (csp0d < csp1d), "");
- static_assert( (csp0s < csp1s), "");
- static_assert( (csp0s < csp1d), "");
- static_assert( (csp0d < csp1s), "");
-
- static_assert(!(csp1d < csp1s), "");
- static_assert(!(csp1s < csp1d), "");
-
- static_assert(!(csp2d < csp3d), "");
- static_assert(!(csp2s < csp3s), "");
- static_assert(!(csp2d < csp3s), "");
- static_assert(!(csp2s < csp3d), "");
-
- static_assert( (csp2d < csp4d), "");
- static_assert( (csp2s < csp4s), "");
- static_assert( (csp2d < csp4s), "");
- static_assert( (csp2s < csp4d), "");
-
- static_assert(!(csp4d < csp2d), "");
- static_assert(!(csp4s < csp2s), "");
- static_assert(!(csp4d < csp2s), "");
- static_assert(!(csp4s < csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert(!(sp0d < sp0d));
- assert(!(sp0s < sp0s));
- assert(!(sp0s < sp0d));
- assert(!(sp0d < sp0s));
-
- assert( (sp0d < sp1d));
- assert( (sp0s < sp1s));
- assert( (sp0s < sp1d));
- assert( (sp0d < sp1s));
-
- assert(!(sp1d < sp1s));
- assert(!(sp1s < sp1d));
-
- assert(!(sp2d < sp3d));
- assert(!(sp2s < sp3s));
- assert(!(sp2d < sp3s));
- assert(!(sp2s < sp3d));
-
- assert( (sp2d < sp4d));
- assert( (sp2s < sp4s));
- assert( (sp2d < sp4s));
- assert( (sp2s < sp4d));
-
- assert(!(sp4d < sp2d));
- assert(!(sp4s < sp2s));
- assert(!(sp4d < sp2s));
- assert(!(sp4s < sp2d));
-
-// cross type comparisons
- assert(!(csp0d < sp0d));
- assert(!(csp0s < sp0s));
- assert(!(csp0s < sp0d));
- assert(!(csp0d < sp0s));
-
- assert( (csp0d < sp1d));
- assert( (csp0s < sp1s));
- assert( (csp0s < sp1d));
- assert( (csp0d < sp1s));
-
- assert(!(csp1d < sp1s));
- assert(!(csp1s < sp1d));
-
- assert(!(csp2d < sp3d));
- assert(!(csp2s < sp3s));
- assert(!(csp2d < sp3s));
- assert(!(csp2s < sp3d));
-
- assert( (csp2d < sp4d));
- assert( (csp2s < sp4s));
- assert( (csp2d < sp4s));
- assert( (csp2s < sp4d));
-
- assert(!(csp4d < sp2d));
- assert(!(csp4s < sp2s));
- assert(!(csp4d < sp2s));
- assert(!(csp4s < sp2d));
-
-// More cross-type comparisons (int vs float)
- static_assert(std::span<const float>{fArr1, 8} < std::span<const int>{iArr1, 9}, "");
- static_assert(std::span<const int>{iArr1, 8} < std::span<const float>{fArr1, 9}, "");
- assert(!(std::span<float>{fArr2} < std::span<int>{iArr2}));
- assert(!(std::span<int>{iArr2} < std::span<float>{fArr2}));
-
- static_assert(!(std::span<const int>{iArr1, 9} < std::span<const float>{fArr1, 8}), "");
-} \ No newline at end of file
diff --git a/test/std/containers/views/span.comparison/op.ne.pass.cpp b/test/std/containers/views/span.comparison/op.ne.pass.cpp
deleted file mode 100644
index ecf05b317491..000000000000
--- a/test/std/containers/views/span.comparison/op.ne.pass.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// -*- C++ -*-
-//===------------------------------ span ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-
-// <span>
-
-// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
-// constexpr bool operator!=(span<T, X> l, span<U, Y> r);
-//
-//
-// Effects: Equivalent to: return !(l == r);
-//
-
-#include <span>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct A{};
-bool operator==(A, A) {return true;}
-
-constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
- int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
-constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
- float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
-
-
-int main () {
-
- constexpr std::span<const int> csp0d{};
- constexpr std::span<const int> csp1d{iArr1, 10};
- constexpr std::span<const int> csp2d{iArr1 + 3, 2};
- constexpr std::span<const int> csp3d{iArr1 + 1, 2};
- constexpr std::span<const int> csp4d{iArr1 + 6, 2};
-
- constexpr std::span<const int, 0> csp0s{};
- constexpr std::span<const int, 10> csp1s{iArr1, 10};
- constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
- constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
- constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
-
- static_assert(!(csp0d != csp0d), "");
- static_assert(!(csp0s != csp0s), "");
- static_assert(!(csp0s != csp0d), "");
- static_assert(!(csp0d != csp0s), "");
-
- static_assert( (csp0d != csp1d), "");
- static_assert( (csp0s != csp1s), "");
- static_assert( (csp0s != csp1d), "");
- static_assert( (csp0d != csp1s), "");
-
- static_assert(!(csp1d != csp1s), "");
- static_assert(!(csp1s != csp1d), "");
-
- static_assert(!(csp2d != csp3d), "");
- static_assert(!(csp2s != csp3s), "");
- static_assert(!(csp2d != csp3s), "");
- static_assert(!(csp2s != csp3d), "");
-
- static_assert(!(csp2d != csp3d), "");
- static_assert(!(csp2s != csp3s), "");
- static_assert(!(csp2d != csp3s), "");
- static_assert(!(csp2s != csp3d), "");
-
- static_assert( (csp2d != csp4d), "");
- static_assert( (csp2s != csp4s), "");
- static_assert( (csp2d != csp4s), "");
- static_assert( (csp2s != csp4d), "");
-
- static_assert( (csp4d != csp2d), "");
- static_assert( (csp4s != csp2s), "");
- static_assert( (csp4d != csp2s), "");
- static_assert( (csp4s != csp2d), "");
-
- std::span<int> sp0d{};
- std::span<int> sp1d{iArr2, 10};
- std::span<int> sp2d{iArr2 + 3, 2};
- std::span<int> sp3d{iArr2 + 1, 2};
- std::span<int> sp4d{iArr2 + 6, 2};
-
- std::span<int, 0> sp0s{};
- std::span<int, 10> sp1s{iArr2, 10};
- std::span<int, 2> sp2s{iArr2 + 3, 2};
- std::span<int, 2> sp3s{iArr2 + 1, 2};
- std::span<int, 2> sp4s{iArr2 + 6, 2};
-
- assert(!(sp0d != sp0d));
- assert(!(sp0s != sp0s));
- assert(!(sp0s != sp0d));
- assert(!(sp0d != sp0s));
-
- assert( (sp0d != sp1d));
- assert( (sp0s != sp1s));
- assert( (sp0s != sp1d));
- assert( (sp0d != sp1s));
-
- assert(!(sp1d != sp1s));
- assert(!(sp1s != sp1d));
-
- assert(!(sp2d != sp3d));
- assert(!(sp2s != sp3s));
- assert(!(sp2d != sp3s));
- assert(!(sp2s != sp3d));
-
- assert(!(sp2d != sp3d));
- assert(!(sp2s != sp3s));
- assert(!(sp2d != sp3s));
- assert(!(sp2s != sp3d));
-
- assert( (sp2d != sp4d));
- assert( (sp2s != sp4s));
- assert( (sp2d != sp4s));
- assert( (sp2s != sp4d));
-
- assert( (sp4d != sp2d));
- assert( (sp4s != sp2s));
- assert( (sp4d != sp2s));
- assert( (sp4s != sp2d));
-
-// cross type comparisons
- assert(!(csp0d != sp0d));
- assert(!(csp0s != sp0s));
- assert(!(csp0s != sp0d));
- assert(!(csp0d != sp0s));
-
- assert( (csp0d != sp1d));
- assert( (csp0s != sp1s));
- assert( (csp0s != sp1d));
- assert( (csp0d != sp1s));
-
- assert(!(csp1d != sp1s));
- assert(!(csp1s != sp1d));
-
- assert(!(csp2d != sp3d));
- assert(!(csp2s != sp3s));
- assert(!(csp2d != sp3s));
- assert(!(csp2s != sp3d));
-
- assert(!(csp2d != sp3d));
- assert(!(csp2s != sp3s));
- assert(!(csp2d != sp3s));
- assert(!(csp2s != sp3d));
-
- assert( (csp2d != sp4d));
- assert( (csp2s != sp4s));
- assert( (csp2d != sp4s));
- assert( (csp2s != sp4d));
-
- assert( (csp4d != sp2d));
- assert( (csp4s != sp2s));
- assert( (csp4d != sp2s));
- assert( (csp4s != sp2d));
-
-// More cross-type comparisons (int vs float)
- static_assert(!(std::span<const float>{fArr1} != std::span<const int>{iArr1}), "");
- static_assert(!(std::span<const int>{iArr1} != std::span<const float>{fArr1}), "");
- assert(!(std::span<float>{fArr2} != std::span<int>{iArr2}));
- assert(!(std::span<int>{iArr2} != std::span<float>{fArr2}));
-
- static_assert( (std::span<const int>{iArr1, 9} != std::span<const float>{fArr1, 8}), "");
-} \ No newline at end of file
diff --git a/test/std/containers/views/span.cons/array.fail.cpp b/test/std/containers/views/span.cons/array.fail.cpp
index 7ef49fc47089..e1e5deea534a 100644
--- a/test/std/containers/views/span.cons/array.fail.cpp
+++ b/test/std/containers/views/span.cons/array.fail.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -16,7 +16,7 @@
// template<size_t N>
// constexpr span(array<value_type, N>& arr) noexcept;
// template<size_t N>
-// constexpr span(const array<value_type, N>& arr) noexcept;
+// constexpr span(const array<value_type, N>& arr) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
@@ -41,13 +41,13 @@ int main ()
{
std::span<int, 2> s1(arr); // expected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
}
-
+
// Type wrong
{
std::span<float> s1(arr); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
-
+
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
diff --git a/test/std/containers/views/span.cons/array.pass.cpp b/test/std/containers/views/span.cons/array.pass.cpp
index 80a0f07f6252..72a86654e1bf 100644
--- a/test/std/containers/views/span.cons/array.pass.cpp
+++ b/test/std/containers/views/span.cons/array.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.cons/assign.pass.cpp b/test/std/containers/views/span.cons/assign.pass.cpp
index b5bd7ae00dfc..cb210046122f 100644
--- a/test/std/containers/views/span.cons/assign.pass.cpp
+++ b/test/std/containers/views/span.cons/assign.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -71,7 +71,7 @@ int main ()
};
static_assert(std::size(spans) == 13, "" );
-
+
// No for loops in constexpr land :-(
static_assert(doAssign(spans[0], spans[0]), "");
static_assert(doAssign(spans[0], spans[1]), "");
@@ -194,7 +194,7 @@ int main ()
{carr2 + 1, 2},
{carr3, 2}
};
-
+
static_assert(std::size(spans) == 6, "" );
// No for loops in constexpr land :-(
@@ -240,7 +240,7 @@ int main ()
{arr, arr + 3},
{arr + 1, arr + 3} // same size as s2
};
-
+
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
@@ -253,7 +253,7 @@ int main ()
{arr + 1, arr + 3},
{arr + 2, arr + 4}
};
-
+
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
@@ -273,7 +273,7 @@ int main ()
{strs + 2, strs + 3},
{strs + 3, strs + 3}
};
-
+
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
@@ -285,7 +285,7 @@ int main ()
{strs + 1, strs + 2},
{strs + 2, strs + 3}
};
-
+
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
diff --git a/test/std/containers/views/span.cons/container.fail.cpp b/test/std/containers/views/span.cons/container.fail.cpp
index ecd7fcb91b83..c8f6830fbc5d 100644
--- a/test/std/containers/views/span.cons/container.fail.cpp
+++ b/test/std/containers/views/span.cons/container.fail.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -89,7 +89,7 @@ int main ()
// Not the same type
{
std::span<float> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
- std::span<float, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
+ std::span<float, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
}
// CV wrong (dynamically sized)
diff --git a/test/std/containers/views/span.cons/container.pass.cpp b/test/std/containers/views/span.cons/container.pass.cpp
index 478a3dac5db7..401f41e07568 100644
--- a/test/std/containers/views/span.cons/container.pass.cpp
+++ b/test/std/containers/views/span.cons/container.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.cons/copy.pass.cpp b/test/std/containers/views/span.cons/copy.pass.cpp
index 2cfffbbd4496..c123acb6a166 100644
--- a/test/std/containers/views/span.cons/copy.pass.cpp
+++ b/test/std/containers/views/span.cons/copy.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -46,7 +46,7 @@ void testCV ()
int main ()
{
constexpr int carr[] = {1,2,3};
-
+
static_assert(doCopy(std::span< int> ()), "");
static_assert(doCopy(std::span< int,0>()), "");
static_assert(doCopy(std::span<const int> (&carr[0], 1)), "");
diff --git a/test/std/containers/views/span.cons/deduct.pass.cpp b/test/std/containers/views/span.cons/deduct.pass.cpp
index e72c09149f03..098215c83951 100644
--- a/test/std/containers/views/span.cons/deduct.pass.cpp
+++ b/test/std/containers/views/span.cons/deduct.pass.cpp
@@ -7,22 +7,22 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, size_t N>
// span(T (&)[N]) -> span<T, N>;
-//
+//
// template<class T, size_t N>
// span(array<T, N>&) -> span<T, N>;
-//
+//
// template<class T, size_t N>
// span(const array<T, N>&) -> span<const T, N>;
-//
+//
// template<class Container>
// span(Container&) -> span<typename Container::value_type>;
-//
+//
// template<class Container>
// span(const Container&) -> span<const typename Container::value_type>;
@@ -66,7 +66,7 @@ int main ()
ASSERT_SAME_TYPE(S, std::span<const long, 5>);
assert((std::equal(std::begin(arr), std::end(arr), s.begin(), s.end())));
}
-
+
{
std::string str{"ABCDE"};
std::span s{str};
diff --git a/test/std/containers/views/span.cons/default.fail.cpp b/test/std/containers/views/span.cons/default.fail.cpp
index d1fefe5b38ca..813939f39ca8 100644
--- a/test/std/containers/views/span.cons/default.fail.cpp
+++ b/test/std/containers/views/span.cons/default.fail.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -25,8 +25,8 @@
int main ()
{
- std::span<int, 2> s; // expected-error@span:* {{static_assert failed "Can't default construct a statically sized span with size > 0"}}
-
+ std::span<int, 2> s; // expected-error-re@span:* {{static_assert failed{{( due to requirement '2[LL]{0,2} == 0')?}} "Can't default construct a statically sized span with size > 0"}}
+
// TODO: This is what I want:
// eXpected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
}
diff --git a/test/std/containers/views/span.cons/default.pass.cpp b/test/std/containers/views/span.cons/default.pass.cpp
index f7e496696e99..b7d01c9e203f 100644
--- a/test/std/containers/views/span.cons/default.pass.cpp
+++ b/test/std/containers/views/span.cons/default.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.cons/ptr_len.fail.cpp b/test/std/containers/views/span.cons/ptr_len.fail.cpp
index db24e3d26884..9ab87f5414b9 100644
--- a/test/std/containers/views/span.cons/ptr_len.fail.cpp
+++ b/test/std/containers/views/span.cons/ptr_len.fail.cpp
@@ -7,12 +7,12 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer ptr, index_type count);
-// Requires: [ptr, ptr + count) shall be a valid range.
+// Requires: [ptr, ptr + count) shall be a valid range.
// If extent is not equal to dynamic_extent, then count shall be equal to extent.
//
@@ -38,7 +38,7 @@ int main ()
std::span<float> s1(arr, 3); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr, 3); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
-
+
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
diff --git a/test/std/containers/views/span.cons/ptr_len.pass.cpp b/test/std/containers/views/span.cons/ptr_len.pass.cpp
index 7302759bcc64..c4e9545e9d97 100644
--- a/test/std/containers/views/span.cons/ptr_len.pass.cpp
+++ b/test/std/containers/views/span.cons/ptr_len.pass.cpp
@@ -7,12 +7,12 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer ptr, index_type count);
-// Requires: [ptr, ptr + count) shall be a valid range.
+// Requires: [ptr, ptr + count) shall be a valid range.
// If extent is not equal to dynamic_extent, then count shall be equal to extent.
//
diff --git a/test/std/containers/views/span.cons/ptr_ptr.fail.cpp b/test/std/containers/views/span.cons/ptr_ptr.fail.cpp
index a55f0592a082..bd4dbab8fca9 100644
--- a/test/std/containers/views/span.cons/ptr_ptr.fail.cpp
+++ b/test/std/containers/views/span.cons/ptr_ptr.fail.cpp
@@ -7,12 +7,12 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer first, pointer last);
-// Requires: [first, last) shall be a valid range.
+// Requires: [first, last) shall be a valid range.
// If extent is not equal to dynamic_extent, then last - first shall be equal to extent.
//
@@ -38,7 +38,7 @@ int main ()
std::span<float> s1(arr, arr + 3); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr, arr + 3); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
-
+
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr, carr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
diff --git a/test/std/containers/views/span.cons/ptr_ptr.pass.cpp b/test/std/containers/views/span.cons/ptr_ptr.pass.cpp
index afb525e73687..c2bceec48a82 100644
--- a/test/std/containers/views/span.cons/ptr_ptr.pass.cpp
+++ b/test/std/containers/views/span.cons/ptr_ptr.pass.cpp
@@ -7,12 +7,12 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer first, pointer last);
-// Requires: [first, last) shall be a valid range.
+// Requires: [first, last) shall be a valid range.
// If extent is not equal to dynamic_extent, then last - first shall be equal to extent.
//
diff --git a/test/std/containers/views/span.cons/span.fail.cpp b/test/std/containers/views/span.cons/span.fail.cpp
index 1fa71551b493..69e879e2ea8a 100644
--- a/test/std/containers/views/span.cons/span.fail.cpp
+++ b/test/std/containers/views/span.cons/span.fail.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -99,6 +99,6 @@ int main ()
std::span<float> s2{sp0}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 0> s3{sp}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
std::span<float, 0> s4{sp0}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
-
+
checkCV();
}
diff --git a/test/std/containers/views/span.cons/span.pass.cpp b/test/std/containers/views/span.cons/span.pass.cpp
index b2024ce123cd..5fdbab22755a 100644
--- a/test/std/containers/views/span.cons/span.pass.cpp
+++ b/test/std/containers/views/span.cons/span.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.cons/stdarray.pass.cpp b/test/std/containers/views/span.cons/stdarray.pass.cpp
index 1832ac2ba497..27623a4c9f74 100644
--- a/test/std/containers/views/span.cons/stdarray.pass.cpp
+++ b/test/std/containers/views/span.cons/stdarray.pass.cpp
@@ -7,14 +7,14 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<size_t N>
// constexpr span(array<value_type, N>& arr) noexcept;
// template<size_t N>
-// constexpr span(const array<value_type, N>& arr) noexcept;
+// constexpr span(const array<value_type, N>& arr) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
diff --git a/test/std/containers/views/span.elem/data.pass.cpp b/test/std/containers/views/span.elem/data.pass.cpp
index 3bc6fbbe5768..ceb2eca17861 100644
--- a/test/std/containers/views/span.elem/data.pass.cpp
+++ b/test/std/containers/views/span.elem/data.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.elem/op_idx.pass.cpp b/test/std/containers/views/span.elem/op_idx.pass.cpp
index a88f4410427a..801eca428666 100644
--- a/test/std/containers/views/span.elem/op_idx.pass.cpp
+++ b/test/std/containers/views/span.elem/op_idx.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -28,7 +28,7 @@ constexpr bool testConstexprSpan(Span sp, ptrdiff_t idx)
{
_LIBCPP_ASSERT(noexcept(sp[idx]), "");
_LIBCPP_ASSERT(noexcept(sp(idx)), "");
-
+
typename Span::reference r1 = sp[idx];
typename Span::reference r2 = sp(idx);
typename Span::reference r3 = *(sp.data() + idx);
@@ -41,7 +41,7 @@ void testRuntimeSpan(Span sp, ptrdiff_t idx)
{
_LIBCPP_ASSERT(noexcept(sp[idx]), "");
_LIBCPP_ASSERT(noexcept(sp(idx)), "");
-
+
typename Span::reference r1 = sp[idx];
typename Span::reference r2 = sp(idx);
typename Span::reference r3 = *(sp.data() + idx);
diff --git a/test/std/containers/views/span.iterators/begin.pass.cpp b/test/std/containers/views/span.iterators/begin.pass.cpp
index c8b9900bc151..cd8d70958f99 100644
--- a/test/std/containers/views/span.iterators/begin.pass.cpp
+++ b/test/std/containers/views/span.iterators/begin.pass.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.iterators/end.pass.cpp b/test/std/containers/views/span.iterators/end.pass.cpp
index 2b64b0f4b541..54ff8ebf7903 100644
--- a/test/std/containers/views/span.iterators/end.pass.cpp
+++ b/test/std/containers/views/span.iterators/end.pass.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -32,8 +32,11 @@ constexpr bool testConstexprSpan(Span s)
}
else
{
+ typename Span::const_pointer last = &*(s.cbegin() + s.size() - 1);
ret = ret && ( e != s.begin());
ret = ret && (ce != s.cbegin());
+ ret = ret && (&*( e-1) == last);
+ ret = ret && (&*(ce-1) == last);
}
ret = ret && (( e - s.begin()) == s.size());
@@ -55,8 +58,11 @@ void testRuntimeSpan(Span s)
}
else
{
+ typename Span::const_pointer last = &*(s.cbegin() + s.size() - 1);
assert( e != s.begin());
assert(ce != s.cbegin());
+ assert( &*( e-1) == last);
+ assert( &*(ce-1) == last);
}
assert(( e - s.begin()) == s.size());
diff --git a/test/std/containers/views/span.iterators/rbegin.pass.cpp b/test/std/containers/views/span.iterators/rbegin.pass.cpp
index c0776c00a81b..258908d6c57f 100644
--- a/test/std/containers/views/span.iterators/rbegin.pass.cpp
+++ b/test/std/containers/views/span.iterators/rbegin.pass.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.iterators/rend.pass.cpp b/test/std/containers/views/span.iterators/rend.pass.cpp
index abcead445e1d..367ea88669e6 100644
--- a/test/std/containers/views/span.iterators/rend.pass.cpp
+++ b/test/std/containers/views/span.iterators/rend.pass.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.objectrep/as_bytes.pass.cpp b/test/std/containers/views/span.objectrep/as_bytes.pass.cpp
index b081b95c373e..e4a240f8da8c 100644
--- a/test/std/containers/views/span.objectrep/as_bytes.pass.cpp
+++ b/test/std/containers/views/span.objectrep/as_bytes.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -38,7 +38,7 @@ void testRuntimeSpan(Span sp)
assert(spBytes.extent == std::dynamic_extent);
else
assert(spBytes.extent == static_cast<std::ptrdiff_t>(sizeof(typename Span::element_type)) * sp.extent);
-
+
assert((void *) spBytes.data() == (void *) sp.data());
assert(spBytes.size() == sp.size_bytes());
}
diff --git a/test/std/containers/views/span.objectrep/as_writeable_bytes.fail.cpp b/test/std/containers/views/span.objectrep/as_writeable_bytes.fail.cpp
index 28a4c45d2477..63d79c923ce4 100644
--- a/test/std/containers/views/span.objectrep/as_writeable_bytes.fail.cpp
+++ b/test/std/containers/views/span.objectrep/as_writeable_bytes.fail.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.objectrep/as_writeable_bytes.pass.cpp b/test/std/containers/views/span.objectrep/as_writeable_bytes.pass.cpp
index 24e3fb273499..54216c2979f6 100644
--- a/test/std/containers/views/span.objectrep/as_writeable_bytes.pass.cpp
+++ b/test/std/containers/views/span.objectrep/as_writeable_bytes.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -38,7 +38,7 @@ void testRuntimeSpan(Span sp)
assert(spBytes.extent == std::dynamic_extent);
else
assert(spBytes.extent == static_cast<std::ptrdiff_t>(sizeof(typename Span::element_type)) * sp.extent);
-
+
assert(static_cast<void*>(spBytes.data()) == static_cast<void*>(sp.data()));
assert(spBytes.size() == sp.size_bytes());
}
diff --git a/test/std/containers/views/span.obs/empty.pass.cpp b/test/std/containers/views/span.obs/empty.pass.cpp
index a48c0d02494b..23e55bb76c6b 100644
--- a/test/std/containers/views/span.obs/empty.pass.cpp
+++ b/test/std/containers/views/span.obs/empty.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -48,7 +48,7 @@ int main ()
static_assert(!std::span<const int>(iArr1, 3).empty(), "");
static_assert(!std::span<const int>(iArr1, 4).empty(), "");
static_assert(!std::span<const int>(iArr1, 5).empty(), "");
-
+
assert( (std::span<int>().empty() ));
assert( (std::span<long>().empty() ));
assert( (std::span<double>().empty() ));
diff --git a/test/std/containers/views/span.obs/size.pass.cpp b/test/std/containers/views/span.obs/size.pass.cpp
index c33fd3f6c61b..16f1b6a7ef73 100644
--- a/test/std/containers/views/span.obs/size.pass.cpp
+++ b/test/std/containers/views/span.obs/size.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.obs/size_bytes.pass.cpp b/test/std/containers/views/span.obs/size_bytes.pass.cpp
index 1ee75d9fcb79..3b6c5b0e2265 100644
--- a/test/std/containers/views/span.obs/size_bytes.pass.cpp
+++ b/test/std/containers/views/span.obs/size_bytes.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/span.sub/first.pass.cpp b/test/std/containers/views/span.sub/first.pass.cpp
index 3bfdab9f8a55..e745fd77df7e 100644
--- a/test/std/containers/views/span.sub/first.pass.cpp
+++ b/test/std/containers/views/span.sub/first.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -114,7 +114,7 @@ int main ()
{
using Sp = std::span<std::string>;
testConstexprSpan<Sp, 0>(Sp{});
-
+
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
@@ -125,7 +125,7 @@ int main ()
{
using Sp = std::span<std::string, 5>;
-
+
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
diff --git a/test/std/containers/views/span.sub/last.pass.cpp b/test/std/containers/views/span.sub/last.pass.cpp
index 4e378fe549ed..94d41430b354 100644
--- a/test/std/containers/views/span.sub/last.pass.cpp
+++ b/test/std/containers/views/span.sub/last.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -114,7 +114,7 @@ int main ()
{
using Sp = std::span<std::string>;
testConstexprSpan<Sp, 0>(Sp{});
-
+
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
@@ -125,7 +125,7 @@ int main ()
{
using Sp = std::span<std::string, 5>;
-
+
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
diff --git a/test/std/containers/views/span.sub/subspan.pass.cpp b/test/std/containers/views/span.sub/subspan.pass.cpp
index 79cdc7bcaf1a..012fc2b5fb44 100644
--- a/test/std/containers/views/span.sub/subspan.pass.cpp
+++ b/test/std/containers/views/span.sub/subspan.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
diff --git a/test/std/containers/views/types.pass.cpp b/test/std/containers/views/types.pass.cpp
index 082abeb774ea..c519fbf768af 100644
--- a/test/std/containers/views/types.pass.cpp
+++ b/test/std/containers/views/types.pass.cpp
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
@@ -25,9 +25,9 @@
// using const_iterator = implementation-defined;
// using reverse_iterator = std::reverse_iterator<iterator>;
// using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-//
+//
// static constexpr index_type extent = Extent;
-//
+//
#include <span>
#include <cassert>
@@ -71,7 +71,7 @@ void testSpan()
ASSERT_SAME_TYPE(typename S::difference_type, std::ptrdiff_t);
ASSERT_SAME_TYPE(typename S::pointer, ElementType *);
ASSERT_SAME_TYPE(typename S::reference, ElementType &);
-
+
static_assert(S::extent == Size); // check that it exists
testIterator<S, typename S::iterator>();
diff --git a/test/std/depr/depr.c.headers/float_h.pass.cpp b/test/std/depr/depr.c.headers/float_h.pass.cpp
index 3001c215cd19..84e89c4dbb84 100644
--- a/test/std/depr/depr.c.headers/float_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/float_h.pass.cpp
@@ -11,6 +11,8 @@
#include <float.h>
+#include "test_macros.h"
+
#ifndef FLT_ROUNDS
#error FLT_ROUNDS not defined
#endif
@@ -23,7 +25,7 @@
#error FLT_RADIX not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_HAS_SUBNORM
#error FLT_HAS_SUBNORM not defined
#endif
@@ -53,7 +55,7 @@
#error DECIMAL_DIG not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_DECIMAL_DIG
#error FLT_DECIMAL_DIG not defined
#endif
@@ -163,7 +165,7 @@
#error LDBL_MIN not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_TRUE_MIN
#error FLT_TRUE_MIN not defined
#endif
diff --git a/test/std/depr/depr.c.headers/math_h.pass.cpp b/test/std/depr/depr.c.headers/math_h.pass.cpp
index 7e1b2d110642..e8341a07f80a 100644
--- a/test/std/depr/depr.c.headers/math_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/math_h.pass.cpp
@@ -14,6 +14,7 @@
#include <cassert>
#include "hexfloat.h"
+#include "truncate_fp.h"
// convertible to int/float/double/etc
template <class T, int N=0>
@@ -807,23 +808,31 @@ void test_atanh()
assert(atanh(0) == 0);
}
-void test_cbrt()
-{
- static_assert((std::is_same<decltype(cbrt((float)0)), float>::value), "");
- static_assert((std::is_same<decltype(cbrt((bool)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((unsigned short)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((int)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((unsigned int)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((long)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((unsigned long)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((long long)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((unsigned long long)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((double)0)), double>::value), "");
- static_assert((std::is_same<decltype(cbrt((long double)0)), long double>::value), "");
+void test_cbrt() {
+ static_assert((std::is_same<decltype(cbrt((float) 0)), float>::value), "");
+ static_assert((std::is_same<decltype(cbrt((bool) 0)), double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((unsigned short) 0)),
+ double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((int) 0)), double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((unsigned int) 0)),
+ double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((long) 0)), double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((unsigned long) 0)),
+ double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((long long) 0)), double>::value),
+ "");
+ static_assert((std::is_same<decltype(cbrt((unsigned long long) 0)),
+ double>::value), "");
+ static_assert((std::is_same<decltype(cbrt((double) 0)), double>::value),
+ "");
+ static_assert((std::is_same<decltype(cbrt((long double) 0)),
+ long double>::value), "");
static_assert((std::is_same<decltype(cbrtf(0)), float>::value), "");
static_assert((std::is_same<decltype(cbrtl(0)), long double>::value), "");
- static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), "");
- assert(cbrt(1) == 1);
+ static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value),
+ "");
+ assert(truncate_fp(cbrt(1)) == 1);
+
}
void test_copysign()
diff --git a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index 07ffa0b75513..cc566d069f7f 100644
--- a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -87,11 +87,9 @@ int main()
static_assert((std::is_same<decltype(srand(0)), void>::value), "");
// Microsoft does not implement aligned_alloc in their C library
-#ifndef TEST_COMPILER_C1XX
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && !defined(_WIN32)
static_assert((std::is_same<decltype(aligned_alloc(0,0)), void*>::value), "");
#endif
-#endif
static_assert((std::is_same<decltype(calloc(0,0)), void*>::value), "");
static_assert((std::is_same<decltype(free(0)), void>::value), "");
diff --git a/test/std/depr/depr.c.headers/uchar_h.pass.cpp b/test/std/depr/depr.c.headers/uchar_h.pass.cpp
index f12169845599..be4ea0dae727 100644
--- a/test/std/depr/depr.c.headers/uchar_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/uchar_h.pass.cpp
@@ -10,6 +10,7 @@
// XFAIL: suse-linux-enterprise-server-11
// XFAIL: apple-darwin
// XFAIL: newlib
+// XFAIL: netbsd
// <uchar.h>
diff --git a/test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.fail.cpp b/test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..652f53181a31
--- /dev/null
+++ b/test/std/depr/depr.lib.binders/depr.lib.bind.1st/bind1st.depr_in_cxx11.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// bind1st
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+
+#include "../test_func.h"
+#include "test_macros.h"
+
+int main()
+{
+ std::bind1st(test_func(1), 5); // expected-error{{'bind1st<test_func, int>' is deprecated}}
+}
diff --git a/test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.fail.cpp b/test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..95cf150cc9fe
--- /dev/null
+++ b/test/std/depr/depr.lib.binders/depr.lib.bind.2nd/bind2nd.depr_in_cxx11.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// bind2nd
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+
+#include "../test_func.h"
+#include "test_macros.h"
+
+int main()
+{
+ std::bind2nd(test_func(1), 5); // expected-error{{'bind2nd<test_func, int>' is deprecated}}
+}
diff --git a/test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.fail.cpp b/test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..8f57eba4d97b
--- /dev/null
+++ b/test/std/depr/depr.lib.binders/depr.lib.binder.1st/binder1st.depr_in_cxx11.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// binder1st
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+
+#include "../test_func.h"
+#include "test_macros.h"
+
+int main()
+{
+ typedef std::binder1st<test_func> B1ST; // expected-error{{'binder1st<test_func>' is deprecated}}
+}
diff --git a/test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.fail.cpp b/test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.fail.cpp
new file mode 100644
index 000000000000..c49334fa0977
--- /dev/null
+++ b/test/std/depr/depr.lib.binders/depr.lib.binder.2nd/binder2nd.depr_in_cxx11.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// binder2nd
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+// MODULES_DEFINES: _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+
+#include "../test_func.h"
+#include "test_macros.h"
+
+int main()
+{
+ typedef std::binder2nd<test_func> B2ND; // expected-error{{'binder2nd<test_func>' is deprecated}}
+}
diff --git a/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp
index c829a97b4228..652100c978b8 100644
--- a/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp
+++ b/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp
@@ -9,14 +9,14 @@
// <strstream>
-// There was an overflow in the dylib on older macOS versions
-// UNSUPPORTED: availability=macosx10.8
-// UNSUPPORTED: availability=macosx10.7
-
// class strstreambuf
// int overflow(int c);
+// There was an overflow in the dylib on older macOS versions
+// UNSUPPORTED: with_system_cxx_lib=macosx10.8
+// UNSUPPORTED: with_system_cxx_lib=macosx10.7
+
#include <iostream>
#include <string>
#include <strstream>
diff --git a/test/std/experimental/simd/simd.access/default.pass.cpp b/test/std/experimental/simd/simd.access/default.pass.cpp
index 6ce32cab8673..d799675a9bc7 100644
--- a/test/std/experimental/simd/simd.access/default.pass.cpp
+++ b/test/std/experimental/simd/simd.access/default.pass.cpp
@@ -165,7 +165,7 @@ void test_access() {
}
{
auto c = a;
- (void)(a[0] + (c[0] <<= a[0]));
+ (void)(a[0] + (c[0] <<= b[0]));
}
{
auto c = a;
diff --git a/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp b/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp
index 7ec814b214e2..a641e92372f6 100644
--- a/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp
+++ b/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/increment.pass.cpp
@@ -32,7 +32,6 @@ TEST_SUITE(directory_iterator_increment_tests)
TEST_CASE(test_increment_signatures)
{
- using D = directory_iterator;
directory_iterator d; ((void)d);
std::error_code ec; ((void)ec);
diff --git a/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp b/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
index 71e8e55ae034..1aa177505e60 100644
--- a/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
+++ b/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
@@ -32,7 +32,6 @@ TEST_SUITE(directory_iterator_begin_end_tests)
TEST_CASE(test_function_signatures)
{
- using D = directory_iterator;
directory_iterator d; ((void)d);
ASSERT_SAME_TYPE(decltype(begin(d)), directory_iterator);
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
index 7791097dcd17..2be6122a0f8c 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
@@ -65,6 +65,8 @@ const PathCompareTest CompareTestCases[] =
{"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
{"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
{"/foo/bar/", "/foo/bar", 1}, // trailing separator
+ {"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0.
+ {"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
{"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
{ LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
@@ -79,7 +81,7 @@ static inline int normalize_ret(int ret)
return ret < 0 ? -1 : (ret > 0 ? 1 : 0);
}
-int main()
+void test_compare_basic()
{
using namespace fs;
for (auto const & TC : CompareTestCases) {
@@ -136,3 +138,54 @@ int main()
}
}
}
+
+int CompareElements(std::vector<std::string> const& LHS, std::vector<std::string> const& RHS) {
+ bool IsLess = std::lexicographical_compare(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
+ if (IsLess)
+ return -1;
+
+ bool IsGreater = std::lexicographical_compare(RHS.begin(), RHS.end(), LHS.begin(), LHS.end());
+ if (IsGreater)
+ return 1;
+
+ return 0;
+}
+
+void test_compare_elements() {
+ struct {
+ std::vector<std::string> LHSElements;
+ std::vector<std::string> RHSElements;
+ int Expect;
+ } TestCases[] = {
+ {{"a"}, {"a"}, 0},
+ {{"a"}, {"b"}, -1},
+ {{"b"}, {"a"}, 1},
+ {{"a", "b", "c"}, {"a", "b", "c"}, 0},
+ {{"a", "b", "c"}, {"a", "b", "d"}, -1},
+ {{"a", "b", "d"}, {"a", "b", "c"}, 1},
+ {{"a", "b"}, {"a", "b", "c"}, -1},
+ {{"a", "b", "c"}, {"a", "b"}, 1},
+
+ };
+
+ auto BuildPath = [](std::vector<std::string> const& Elems) {
+ fs::path p;
+ for (auto &E : Elems)
+ p /= E;
+ return p;
+ };
+
+ for (auto &TC : TestCases) {
+ fs::path LHS = BuildPath(TC.LHSElements);
+ fs::path RHS = BuildPath(TC.RHSElements);
+ const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements);
+ assert(ExpectCmp == TC.Expect);
+ const int GotCmp = normalize_ret(LHS.compare(RHS));
+ assert(GotCmp == TC.Expect);
+ }
+}
+
+int main() {
+ test_compare_basic();
+ test_compare_elements();
+}
diff --git a/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp b/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
index 52c577bc8a71..f4e1d2f74dff 100644
--- a/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
@@ -40,8 +40,8 @@ int main() {
{"a", "/", ""},
{"//net", "a", ""},
{"a", "//net", ""},
- {"//net/", "//net", ""},
- {"//net", "//net/", ".."},
+ {"//net/", "//net", "."},
+ {"//net", "//net/", "."},
{"//base", "a", ""},
{"a", "a", "."},
{"a/b", "a/b", "."},
diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp
new file mode 100644
index 000000000000..e0b3a959c29f
--- /dev/null
+++ b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.fail.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+#include "filesystem_include.hpp"
+
+using namespace fs;
+
+struct ConvToPath {
+ operator fs::path() const {
+ return "";
+ }
+};
+
+int main() {
+ ConvToPath LHS, RHS;
+ (void)(LHS / RHS); // expected-error {{invalid operands to binary expression}}
+} \ No newline at end of file
diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp
index 09498bf2135a..2a291d61da7c 100644
--- a/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp
+++ b/test/std/input.output/filesystems/class.path/path.nonmember/append_op.pass.cpp
@@ -20,7 +20,6 @@
#include "test_macros.h"
#include "filesystem_test_helper.hpp"
-
// This is mainly tested via the member append functions.
int main()
{
@@ -29,4 +28,7 @@ int main()
path p2("def");
path p3 = p1 / p2;
assert(p3 == "abc/def");
+
+ path p4 = p1 / "def";
+ assert(p4 == "abc/def");
}
diff --git a/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp b/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp
new file mode 100644
index 000000000000..00eafe532d08
--- /dev/null
+++ b/test/std/input.output/filesystems/class.path/path.nonmember/comparison_ops.fail.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <filesystem>
+
+
+#include "filesystem_include.hpp"
+
+using namespace fs;
+
+struct ConvToPath {
+ operator fs::path() const {
+ return "";
+ }
+};
+
+int main() {
+ ConvToPath LHS, RHS;
+ (void)(LHS == RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS != RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS < RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS <= RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS > RHS); // expected-error {{invalid operands to binary expression}}
+ (void)(LHS >= RHS); // expected-error {{invalid operands to binary expression}}
+} \ No newline at end of file
diff --git a/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp b/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
index bfc818924d18..2d30cc3b84d2 100644
--- a/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
+++ b/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
@@ -31,7 +31,6 @@ TEST_SUITE(recursive_directory_iterator_increment_tests)
TEST_CASE(test_increment_signatures)
{
- using D = recursive_directory_iterator;
recursive_directory_iterator d; ((void)d);
std::error_code ec; ((void)ec);
diff --git a/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp b/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
index 04bc2dd1d96b..9807309f44a4 100644
--- a/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
+++ b/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
@@ -32,7 +32,6 @@ TEST_SUITE(recursive_directory_iterator_begin_end_tests)
TEST_CASE(test_function_signatures)
{
- using D = recursive_directory_iterator;
recursive_directory_iterator d; ((void)d);
ASSERT_SAME_TYPE(decltype(begin(d)), recursive_directory_iterator);
diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
index bc77f3f6351b..bf0096acff19 100644
--- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
+++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
@@ -108,7 +108,6 @@ struct Times {
};
Times GetTimes(path const& p) {
- using Clock = file_time_type::clock;
StatT st;
if (::stat(p.c_str(), &st) == -1) {
std::error_code ec(errno, std::generic_category());
@@ -126,8 +125,7 @@ TimeSpec LastAccessTime(path const& p) { return GetTimes(p).access; }
TimeSpec LastWriteTime(path const& p) { return GetTimes(p).write; }
-std::pair<TimeSpec, TimeSpec> GetSymlinkTimes(path const& p) {
- using Clock = file_time_type::clock;
+Times GetSymlinkTimes(path const& p) {
StatT st;
if (::lstat(p.c_str(), &st) == -1) {
std::error_code ec(errno, std::generic_category());
@@ -138,7 +136,10 @@ std::pair<TimeSpec, TimeSpec> GetSymlinkTimes(path const& p) {
std::exit(EXIT_FAILURE);
#endif
}
- return {extract_atime(st), extract_mtime(st)};
+ Times res;
+ res.access = extract_atime(st);
+ res.write = extract_mtime(st);
+ return res;
}
namespace {
@@ -429,7 +430,7 @@ TEST_CASE(set_last_write_time_dynamic_env_test)
epoch_time - Minutes(3) - Sec(42) - SubSec(17);
// FreeBSD has a bug in their utimes implementation where the time is not update
// when the number of seconds is '-1'.
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__)
const file_time_type just_before_epoch_time =
epoch_time - Sec(2) - SubSec(17);
#else
@@ -502,15 +503,13 @@ TEST_CASE(last_write_time_symlink_test)
TEST_CHECK(CompareTime(LastWriteTime(file), new_time));
TEST_CHECK(CompareTime(LastAccessTime(sym), old_times.access));
- std::pair<TimeSpec, TimeSpec> sym_times = GetSymlinkTimes(sym);
- TEST_CHECK(CompareTime(sym_times.first, old_sym_times.first));
- TEST_CHECK(CompareTime(sym_times.second, old_sym_times.second));
+ Times sym_times = GetSymlinkTimes(sym);
+ TEST_CHECK(CompareTime(sym_times.write, old_sym_times.write));
}
TEST_CASE(test_write_min_time)
{
- using Clock = file_time_type::clock;
scoped_test_env env;
const path p = env.create_file("file", 42);
const file_time_type old_time = last_write_time(p);
@@ -545,10 +544,6 @@ TEST_CASE(test_write_min_time)
}
TEST_CASE(test_write_max_time) {
- using Clock = file_time_type::clock;
- using Sec = std::chrono::seconds;
- using Hours = std::chrono::hours;
-
scoped_test_env env;
const path p = env.create_file("file", 42);
const file_time_type old_time = last_write_time(p);
diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
index cbe2b2d09fb3..b5fb838dd860 100644
--- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
+++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp
@@ -159,7 +159,7 @@ TEST_CASE(test_no_resolve_symlink_on_symlink)
{perms::owner_all, perms::group_all, perm_options::remove},
};
for (auto const& TC : cases) {
-#if defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
// On OS X symlink permissions are supported. We should get an empty
// error code and the expected permissions.
const auto expected_link_perms = TC.expected;
diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
index 5f7b30dd60b9..ec4fc6d91010 100644
--- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
+++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
@@ -75,12 +75,12 @@ TEST_CASE(basic_test) {
{"a", parent_cwd, "fs.op.proximate/a"},
{"/", "a", dot_dot_to_root / ".."},
{"/", "a/b", dot_dot_to_root / "../.."},
- {"/", "a/b/", dot_dot_to_root / "../../.."},
+ {"/", "a/b/", dot_dot_to_root / "../.."},
{"a", "/", relative_cwd / "a"},
{"a/b", "/", relative_cwd / "a/b"},
{"a", "/net", ".." / relative_cwd / "a"},
- {"//foo/", "//foo", "/foo/"},
- {"//foo", "//foo/", ".."},
+ {"//foo/", "//foo", "."},
+ {"//foo", "//foo/", "."},
{"//foo", "//foo", "."},
{"//foo/", "//foo/", "."},
{"//base", "a", dot_dot_to_root / "../base"},
diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
index e240c6496755..940f886f9977 100644
--- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
+++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
@@ -16,9 +16,8 @@
// path proximate(const path& p, const path& base, error_code& ec);
#include "filesystem_include.hpp"
+#include <string>
#include <type_traits>
-#include <vector>
-#include <iostream>
#include <cassert>
#include "test_macros.h"
@@ -30,49 +29,90 @@
TEST_SUITE(filesystem_proximate_path_test_suite)
-TEST_CASE(test_signature) {
+TEST_CASE(test_signature_0) {
+ fs::path p("");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(fs::current_path()));
+}
+
+TEST_CASE(test_signature_1) {
+ fs::path p(".");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(fs::current_path()));
+}
+
+TEST_CASE(test_signature_2) {
+ fs::path p(StaticEnv::File);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::File));
+}
+
+TEST_CASE(test_signature_3) {
+ fs::path p(StaticEnv::Dir);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_4) {
+ fs::path p(StaticEnv::SymlinkToDir);
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_5) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/.");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2"));
+}
+
+TEST_CASE(test_signature_6) {
+ // FIXME? If the trailing separator occurs in a part of the path that exists,
+ // it is ommitted. Otherwise it is added to the end of the result.
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/./");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2"));
+}
+
+TEST_CASE(test_signature_7) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/DNE/./");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2/DNE/"));
+}
+
+TEST_CASE(test_signature_8) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2));
+}
+
+TEST_CASE(test_signature_9) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2 / ""));
+}
+
+TEST_CASE(test_signature_10) {
+ fs::path p(StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir2 / "DNE/DNE2"));
+}
+TEST_CASE(test_signature_11) {
+ fs::path p(StaticEnv::Dir / "../dir1");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
}
-int main() {
- // clang-format off
- struct {
- std::string input;
- std::string expect;
- } TestCases[] = {
- {"", fs::current_path()},
- {".", fs::current_path()},
- {StaticEnv::File, StaticEnv::File},
- {StaticEnv::Dir, StaticEnv::Dir},
- {StaticEnv::SymlinkToDir, StaticEnv::Dir},
- {StaticEnv::SymlinkToDir / "dir2/.", StaticEnv::Dir / "dir2"},
- // FIXME? If the trailing separator occurs in a part of the path that exists,
- // it is ommitted. Otherwise it is added to the end of the result.
- {StaticEnv::SymlinkToDir / "dir2/./", StaticEnv::Dir / "dir2"},
- {StaticEnv::SymlinkToDir / "dir2/DNE/./", StaticEnv::Dir / "dir2/DNE/"},
- {StaticEnv::SymlinkToDir / "dir2", StaticEnv::Dir2},
- {StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..", StaticEnv::Dir2 / ""},
- {StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2", StaticEnv::Dir2 / "DNE/DNE2"},
- {StaticEnv::Dir / "../dir1", StaticEnv::Dir},
- {StaticEnv::Dir / "./.", StaticEnv::Dir},
- {StaticEnv::Dir / "DNE/../foo", StaticEnv::Dir / "foo"}
- };
- // clang-format on
- int ID = 0;
- bool Failed = false;
- for (auto& TC : TestCases) {
- ++ID;
- fs::path p(TC.input);
- const fs::path output = fs::weakly_canonical(p);
- if (output != TC.expect) {
- Failed = true;
- std::cerr << "TEST CASE #" << ID << " FAILED: \n";
- std::cerr << " Input: '" << TC.input << "'\n";
- std::cerr << " Expected: '" << TC.expect << "'\n";
- std::cerr << " Output: '" << output.native() << "'";
- std::cerr << std::endl;
- }
- }
- return Failed;
+
+TEST_CASE(test_signature_12) {
+ fs::path p(StaticEnv::Dir / "./.");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir));
+}
+
+TEST_CASE(test_signature_13) {
+ fs::path p(StaticEnv::Dir / "DNE/../foo");
+ const fs::path output = fs::weakly_canonical(p);
+ TEST_CHECK(output == std::string(StaticEnv::Dir / "foo"));
}
TEST_SUITE_END()
diff --git a/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp b/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp
index 1ea1d780c50f..34b65f52dbd1 100644
--- a/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp
+++ b/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp
@@ -14,6 +14,7 @@
// REQUIRES: locale.en_US.UTF-8
#include <iomanip>
+#include <istream>
#include <cassert>
#include "platform_support.h" // locale name macros
diff --git a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp
index 553c2b2eb3a0..7c653f348aef 100644
--- a/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp
+++ b/test/std/input.output/iostream.format/ext.manip/get_time.pass.cpp
@@ -14,6 +14,7 @@
// template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
#include <iomanip>
+#include <istream>
#include <cassert>
#include "platform_support.h" // locale name macros
diff --git a/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp b/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp
index 342e33724cc7..92b6c726e755 100644
--- a/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp
+++ b/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp
@@ -14,6 +14,7 @@
// REQUIRES: locale.en_US.UTF-8
#include <iomanip>
+#include <ostream>
#include <cassert>
#include "platform_support.h" // locale name macros
diff --git a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp
index dae74f0401f8..915efd081b49 100644
--- a/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp
+++ b/test/std/input.output/iostream.format/ext.manip/put_time.pass.cpp
@@ -14,6 +14,7 @@
// template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
#include <iomanip>
+#include <ostream>
#include <cassert>
#include "platform_support.h" // locale name macros
diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
index 25687db16f37..8d1261137f84 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
@@ -15,6 +15,7 @@
// operator>>(int& val);
#include <istream>
+#include <limits>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
index 62e44f542a64..22a760da6337 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
@@ -15,6 +15,7 @@
// operator>>(short& val);
#include <istream>
+#include <limits>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
index 70f1c20108fc..b815246d6c1f 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
@@ -61,6 +61,17 @@ int main()
assert(std::string((char*)s) == "abc");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk ");
+ std::istream is(&sb);
+ signed char s[4];
+ is >> s;
+ assert(!is.eof());
+ assert(!is.fail());
+ assert(std::string((char*)s) == "abc");
+ }
+#endif
{
testbuf<char> sb(" abcdefghijk");
std::istream is(&sb);
@@ -82,4 +93,15 @@ int main()
assert(std::string((char*)s) == "");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk");
+ std::istream is(&sb);
+ signed char s[1];
+ is >> s;
+ assert(!is.eof());
+ assert( is.fail());
+ assert(std::string((char*)s) == "");
+ }
+#endif
}
diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
index 07fa5a79e8f2..1e98b7dfdbd8 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
@@ -61,6 +61,17 @@ int main()
assert(std::string((char*)s) == "abc");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk ");
+ std::istream is(&sb);
+ unsigned char s[4];
+ is >> s;
+ assert(!is.eof());
+ assert(!is.fail());
+ assert(std::string((char*)s) == "abc");
+ }
+#endif
{
testbuf<char> sb(" abcdefghijk");
std::istream is(&sb);
@@ -82,4 +93,15 @@ int main()
assert(std::string((char*)s) == "");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk");
+ std::istream is(&sb);
+ unsigned char s[1];
+ is >> s;
+ assert(!is.eof());
+ assert( is.fail());
+ assert(std::string((char*)s) == "");
+ }
+#endif
}
diff --git a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
index a00c7a1dda38..82e460db927b 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
@@ -50,6 +50,17 @@ int main()
assert(!is.fail());
assert(std::string(s) == "abcdefghijk");
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk ");
+ std::istream is(&sb);
+ char s[4];
+ is >> s;
+ assert(!is.eof());
+ assert(!is.fail());
+ assert(std::string(s) == "abc");
+ }
+#endif
{
testbuf<wchar_t> sb(L" abcdefghijk ");
std::wistream is(&sb);
@@ -71,6 +82,17 @@ int main()
assert(std::wstring(s) == L"abcdefghijk");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<wchar_t> sb(L" abcdefghijk");
+ std::wistream is(&sb);
+ wchar_t s[4];
+ is >> s;
+ assert(!is.eof());
+ assert(!is.fail());
+ assert(std::wstring(s) == L"abc");
+ }
+#endif
{
testbuf<char> sb(" abcdefghijk");
std::istream is(&sb);
@@ -82,4 +104,15 @@ int main()
assert(std::string(s) == "");
assert(is.width() == 0);
}
+#if TEST_STD_VER > 17
+ {
+ testbuf<char> sb(" abcdefghijk");
+ std::istream is(&sb);
+ char s[1];
+ is >> s;
+ assert(!is.eof());
+ assert( is.fail());
+ assert(std::string(s) == "");
+ }
+#endif
}
diff --git a/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
index 77c41b09ad7b..230a59a88ae5 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
@@ -65,7 +65,7 @@ int main()
{ // test perfect forwarding
assert(called == false);
std::istringstream ss;
- auto& out = (std::move(ss) >> A{});
+ auto&& out = (std::move(ss) >> A{});
assert(&out == &ss);
assert(called);
}
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
index c7f16ca7e385..0f356e26d237 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-
// <istream>
// int_type get();
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
index b3d3c69b43d3..cf06e343bcc2 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-
// <istream>
// basic_istream<charT,traits>& get(char_type& c);
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
index a45802c571dd..83fd40befa66 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they
+// have a bug in how they handle null-termination in case of errors (see D40677).
+// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.8
-// XFAIL: with_system_cxx_lib=macosx10.7
// <istream>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
index 437af84f9d61..8b42bae5592a 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they
+// have a bug in how they handle null-termination in case of errors (see D40677).
+// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.8
-// XFAIL: with_system_cxx_lib=macosx10.7
// <istream>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
index 7ee2c295636b..f17aa1623033 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they
+// have a bug in how they handle null-termination in case of errors (see D40677).
+// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.8
-// XFAIL: with_system_cxx_lib=macosx10.7
// <istream>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
index 1bce3fa5d4a5..5c6a3c59ffc5 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they
+// have a bug in how they handle null-termination in case of errors (see D40677).
+// XFAIL: with_system_cxx_lib=macosx10.14
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.8
-// XFAIL: with_system_cxx_lib=macosx10.7
// <istream>
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp
index 3a37cffce3af..3095712b9dbc 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore_0xff.pass.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
-
// <istream>
// basic_istream<charT,traits>&
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
index ceef0d28fc6b..20e70cfbd5cd 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-
// <istream>
// basic_istream<charT,traits>& read(char_type* s, streamsize n);
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
index a0a8e2f1b3b3..01eecb5d824b 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
-
// <istream>
// streamsize readsome(char_type* s, streamsize n);
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
index e370b4bfb009..dc4e0ba0de20 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
-
// <istream>
// basic_istream<charT,traits>& seekg(pos_type pos);
diff --git a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
index cac1e39554ed..3b7417ab23e7 100644
--- a/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
+++ b/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
@@ -7,12 +7,9 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
// <istream>
diff --git a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp
index 956cd171a1de..c23b3028cf41 100644
--- a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp
+++ b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minmax_showbase.pass.cpp
@@ -24,6 +24,12 @@
// Testing to make sure that the max length values are correctly inserted when
// using std::showbase
+// This test exposes a regression that was not fixed yet in the libc++
+// shipped with macOS 10.12, 10.13 and 10.14. See D32670 for details.
+// XFAIL: with_system_cxx_lib=macosx10.14
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+
#include <cassert>
#include <cstdint>
#include <ios>
@@ -40,7 +46,7 @@ static void test(std::ios_base::fmtflags fmt, const char *expected)
assert(ss.str() == expected);
}
-int main(void)
+int main()
{
const std::ios_base::fmtflags o = std::ios_base::oct;
const std::ios_base::fmtflags d = std::ios_base::dec;
diff --git a/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp b/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp
index 6c01fc057da4..b0b3c31f7a89 100644
--- a/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/resetiosflags.pass.cpp
@@ -12,6 +12,8 @@
// T1 resetiosflags(ios_base::fmtflags mask);
#include <iomanip>
+#include <istream>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp b/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp
index e2776a5d1ab3..0a2fb36ec6e3 100644
--- a/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/setbase.pass.cpp
@@ -12,6 +12,8 @@
// T3 setbase(int base);
#include <iomanip>
+#include <istream>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp b/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp
index a4d923d70ade..e8600972d9f8 100644
--- a/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/setfill.pass.cpp
@@ -12,6 +12,7 @@
// template<charT> T4 setfill(charT c);
#include <iomanip>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp b/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp
index 5aaf38444ab1..11532711a854 100644
--- a/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/setiosflags.pass.cpp
@@ -12,6 +12,8 @@
// T2 setiosflags (ios_base::fmtflags mask);
#include <iomanip>
+#include <istream>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp b/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp
index 0bea4b98623b..e04677fa346e 100644
--- a/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/setprecision.pass.cpp
@@ -12,6 +12,8 @@
// T5 setprecision(int n);
#include <iomanip>
+#include <istream>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostream.format/std.manip/setw.pass.cpp b/test/std/input.output/iostream.format/std.manip/setw.pass.cpp
index 9bd96984e5c9..3242bcc947d4 100644
--- a/test/std/input.output/iostream.format/std.manip/setw.pass.cpp
+++ b/test/std/input.output/iostream.format/std.manip/setw.pass.cpp
@@ -12,6 +12,8 @@
// T6 setw(int n);
#include <iomanip>
+#include <istream>
+#include <ostream>
#include <cassert>
template <class CharT>
diff --git a/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp b/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp
index bf865e68149d..3cdb434c4a8c 100644
--- a/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/basic.ios.members/narrow.pass.cpp
@@ -18,7 +18,7 @@
int main()
{
- const std::ios ios(0);
- assert(ios.narrow('c', '*') == 'c');
- assert(ios.narrow('\xFE', '*') == '*');
+ const std::wios ios(0);
+ assert(ios.narrow(L'c', '*') == 'c');
+ assert(ios.narrow(L'\u203C', '*') == '*');
}
diff --git a/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp b/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp
new file mode 100644
index 000000000000..0fab1aa15e83
--- /dev/null
+++ b/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+
+// struct iterator_traits
+// {
+// };
+
+#include <iterator>
+#include "test_macros.h"
+
+struct A {};
+struct NotAnIteratorEmpty {};
+
+struct NotAnIteratorNoDifference
+{
+// typedef int difference_type;
+ typedef A value_type;
+ typedef A* pointer;
+ typedef A& reference;
+ typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoValue
+{
+ typedef int difference_type;
+// typedef A value_type;
+ typedef A* pointer;
+ typedef A& reference;
+ typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoPointer
+{
+ typedef int difference_type;
+ typedef A value_type;
+// typedef A* pointer;
+ typedef A& reference;
+ typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoReference
+{
+ typedef int difference_type;
+ typedef A value_type;
+ typedef A* pointer;
+// typedef A& reference;
+ typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoCategory
+{
+ typedef int difference_type;
+ typedef A value_type;
+ typedef A* pointer;
+ typedef A& reference;
+// typedef std::forward_iterator_tag iterator_category;
+};
+
+int main()
+{
+ {
+ typedef std::iterator_traits<NotAnIteratorEmpty> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoDifference> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoValue> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoPointer> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoReference> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoCategory> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::{{.+}}::iterator_traits<{{.+}}>}}
+ }
+}
diff --git a/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp b/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp
index 38f7c0b6b833..34f430ff3ee7 100644
--- a/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp
+++ b/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp
@@ -39,5 +39,6 @@ int main()
static_assert((std::is_same<It::difference_type, int>::value), "");
static_assert((std::is_same<It::value_type, A>::value), "");
static_assert((std::is_same<It::pointer, A*>::value), "");
+ static_assert((std::is_same<It::reference, A&>::value), "");
static_assert((std::is_same<It::iterator_category, std::forward_iterator_tag>::value), "");
}
diff --git a/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp b/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp
index a80477151ef2..4ea823499b5e 100644
--- a/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp
+++ b/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp
@@ -130,7 +130,7 @@ constexpr bool test_constexpr() {
};
for (auto TC : SpaceshipTestCases)
{
- std::partial_ordering Res = (0 <=> TC.Value);
+ std::partial_ordering Res = (TC.Value <=> 0);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
diff --git a/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp b/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp
index 0bdd68679b44..94668ab7c47c 100644
--- a/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp
+++ b/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp
@@ -185,7 +185,7 @@ constexpr bool test_constexpr() {
};
for (auto TC : SpaceshipTestCases)
{
- std::strong_ordering Res = (0 <=> TC.Value);
+ std::strong_ordering Res = (TC.Value <=> 0);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
diff --git a/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp b/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp
index 0a52680323b2..067f378e0bfd 100644
--- a/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp
+++ b/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp
@@ -142,7 +142,7 @@ constexpr bool test_constexpr() {
};
for (auto TC : SpaceshipTestCases)
{
- std::weak_ordering Res = (0 <=> TC.Value);
+ std::weak_ordering Res = (TC.Value <=> 0);
switch (TC.Expect) {
case ER_Equiv:
assert(Res == 0);
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
index 2175e29a040d..4dd9390c4fdc 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
@@ -12,17 +12,30 @@
// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
// Older Clang versions do not support this
-// XFAIL: clang-3, apple-clang-7, apple-clang-8
+// UNSUPPORTED: clang-3, apple-clang-7, apple-clang-8
// None of the current GCC compilers support this.
-// XFAIL: gcc-5, gcc-6
-
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// UNSUPPORTED: gcc-5, gcc-6
+
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// On Windows libc++ doesn't provide its own definitions for new/delete
// but instead depends on the ones in VCRuntime. However VCRuntime does not
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
index 942f5e778b66..d6194b00aa02 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
@@ -15,13 +15,25 @@
// FIXME change this to XFAIL.
// UNSUPPORTED: no-aligned-allocation && !gcc
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
-
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// On Windows libc++ doesn't provide its own definitions for new/delete
// but instead depends on the ones in VCRuntime. However VCRuntime does not
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
index f55ad5bcc84e..59878aefd18a 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
@@ -15,12 +15,25 @@
// FIXME turn this into an XFAIL
// UNSUPPORTED: no-aligned-allocation && !gcc
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// On Windows libc++ doesn't provide its own definitions for new/delete
// but instead depends on the ones in VCRuntime. However VCRuntime does not
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
index e1ebf86ee176..fc713dbf8ed8 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
@@ -10,12 +10,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// XFAIL: no-aligned-allocation && !gcc
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.fail.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.sh.cpp
index 0dfef2e56fca..40632a1bd49b 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.fail.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.sh.cpp
@@ -15,11 +15,12 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
-#include <new>
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
-#include "test_macros.h"
+#include <new>
int main ()
{
- ::operator new[](4); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](4); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.sh.cpp
new file mode 100644
index 000000000000..f7921d2f2c12
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.sh.cpp
@@ -0,0 +1,26 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <new>
+
+// void* operator new[](std::size_t, std::align_val_t);
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
+
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
+
+#include <new>
+
+int main ()
+{
+ ::operator new[](4, std::align_val_t{4}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.fail.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.sh.cpp
index 99e4f76b312f..130148786732 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.fail.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.sh.cpp
@@ -15,11 +15,12 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
-#include <new>
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
-#include "test_macros.h"
+#include <new>
int main ()
{
- ::operator new[](4, std::align_val_t{4}, std::nothrow); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](4, std::align_val_t{4}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.fail.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.sh.cpp
index 8aae54e83fbe..43295a7e6932 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.fail.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.sh.cpp
@@ -15,11 +15,12 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
-#include <new>
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
-#include "test_macros.h"
+#include <new>
int main ()
{
- ::operator new[](4, std::nothrow); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](4, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp
index f71cf19cc80b..ab25a9be0086 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp
@@ -13,15 +13,15 @@
// when sized deallocation is not supported, e.g., prior to C++14.
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: availability_markup=macosx10.11
-// XFAIL: availability_markup=macosx10.10
-// XFAIL: availability_markup=macosx10.9
-// XFAIL: availability_markup=macosx10.8
-// XFAIL: availability_markup=macosx10.7
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation.
-// REQUIRES: fsized-deallocation
+// REQUIRES: -fsized-deallocation
// RUN: %build -fsized-deallocation
// RUN: %run
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
index 6f1c7511243e..19cabcce1edd 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
@@ -11,17 +11,30 @@
// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
// Older Clang versions do not support this
-// XFAIL: clang-3, apple-clang-7, apple-clang-8
+// UNSUPPORTED: clang-3, apple-clang-7, apple-clang-8
// None of the current GCC compilers support this.
-// XFAIL: gcc-5, gcc-6
-
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// UNSUPPORTED: gcc-5, gcc-6
+
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// On Windows libc++ doesn't provide its own definitions for new/delete
// but instead depends on the ones in VCRuntime. However VCRuntime does not
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
index fae5d3676df6..7cf1aca3b9f8 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
@@ -9,12 +9,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// asan and msan will not call the new handler.
// UNSUPPORTED: sanitizer-new-delete
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
index f22c48994355..dd2666e00aad 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
@@ -9,12 +9,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// asan and msan will not call the new handler.
// UNSUPPORTED: sanitizer-new-delete
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
index 565ba9b851bb..514a2b8afc8c 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
@@ -10,12 +10,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// Aligned allocation was not provided before macosx10.12 and as a result we
+// get availability errors when the deployment target is older than macosx10.13.
+// However, AppleClang 10 (and older) don't trigger availability errors.
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
+// XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
+
+// On AppleClang 10 (and older), instead of getting an availability failure
+// like above, we get a link error when we link against a dylib that does
+// not export the aligned allocation functions.
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
+// XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
// NOTE: gcc doesn't provide -faligned-allocation flag to test for
// XFAIL: no-aligned-allocation && !gcc
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.fail.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.sh.cpp
index ea041aea16ee..410c6d7748da 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.fail.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.sh.cpp
@@ -10,16 +10,17 @@
// <new>
-// void* operator new[](std::size_t, std::align_val_t);
+// void* operator new(std::size_t, std::align_val_t);
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
-#include <new>
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
-#include "test_macros.h"
+#include <new>
int main ()
{
- ::operator new[](4, std::align_val_t{4}); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(4, std::align_val_t{4}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.fail.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.sh.cpp
index e987a53478b0..1fe104551e1b 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.fail.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.sh.cpp
@@ -15,11 +15,12 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
-#include <new>
+// REQUIRES: -faligned-allocation
+// RUN: %compile %verify -faligned-allocation
-#include "test_macros.h"
+#include <new>
int main ()
{
- ::operator new(4, std::align_val_t{4}, std::nothrow); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(4, std::align_val_t{4}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
index d5b610f71802..7d6f34845f7e 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
@@ -13,14 +13,14 @@
// when sized deallocation is not supported, e.g., prior to C++14.
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: availability_markup=macosx10.11
-// XFAIL: availability_markup=macosx10.10
-// XFAIL: availability_markup=macosx10.9
-// XFAIL: availability_markup=macosx10.8
-// XFAIL: availability_markup=macosx10.7
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation.
-// REQUIRES: fsized-deallocation
+// REQUIRES: -fsized-deallocation
// RUN: %build -fsized-deallocation -O3
// RUN: %run
diff --git a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp
index 71f5e4588b82..034c578bbf3b 100644
--- a/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp
+++ b/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp
@@ -29,6 +29,8 @@ int main ()
(void) std::launder((const void *) nullptr);
(void) std::launder(( volatile void *) nullptr);
(void) std::launder((const volatile void *) nullptr); // expected-error-re@new:* 4 {{static_assert failed{{.*}} "can't launder cv-void"}}
+ // expected-error@new:* 0-4 {{void pointer argument to '__builtin_launder' is not allowed}}
(void) std::launder(foo); // expected-error-re@new:* 1 {{static_assert failed{{.*}} "can't launder functions"}}
+ // expected-error@new:* 0-1 {{function pointer argument to '__builtin_launder' is not allowed}}
}
diff --git a/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
index d030d12d2630..859d831a3329 100644
--- a/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
+++ b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
@@ -10,11 +10,11 @@
// UNSUPPORTED: libcpp-no-exceptions
// XFAIL: libcpp-no-exceptions
-// XFAIL: availability=macosx10.7
-// XFAIL: availability=macosx10.8
-// XFAIL: availability=macosx10.9
-// XFAIL: availability=macosx10.10
-// XFAIL: availability=macosx10.11
+// XFAIL: macosx10.7
+// XFAIL: macosx10.8
+// XFAIL: macosx10.9
+// XFAIL: macosx10.10
+// XFAIL: macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.13
diff --git a/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp b/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
index 6e399d0934bf..c1e5be91ef1f 100644
--- a/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
+++ b/test/std/language.support/support.limits/c.limits/cfloat.pass.cpp
@@ -11,6 +11,8 @@
#include <cfloat>
+#include "test_macros.h"
+
#ifndef FLT_ROUNDS
#error FLT_ROUNDS not defined
#endif
@@ -23,7 +25,7 @@
#error FLT_RADIX not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_HAS_SUBNORM
#error FLT_HAS_SUBNORM not defined
#endif
@@ -53,7 +55,7 @@
#error DECIMAL_DIG not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_DECIMAL_DIG
#error FLT_DECIMAL_DIG not defined
#endif
@@ -163,7 +165,7 @@
#error LDBL_MIN not defined
#endif
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && 0
#ifndef FLT_TRUE_MIN
#error FLT_TRUE_MIN not defined
#endif
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp
index 6a46c370e750..11772f67dd58 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/const_data_members.pass.cpp
@@ -9,6 +9,8 @@
#include <limits>
+#include "test_macros.h"
+
/*
<limits>:
numeric_limits
@@ -99,6 +101,14 @@ int main()
TEST_NUMERIC_LIMITS(volatile wchar_t)
TEST_NUMERIC_LIMITS(const volatile wchar_t)
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ // char8_t
+ TEST_NUMERIC_LIMITS(char8_t)
+ TEST_NUMERIC_LIMITS(const char8_t)
+ TEST_NUMERIC_LIMITS(volatile char8_t)
+ TEST_NUMERIC_LIMITS(const volatile char8_t)
+#endif
+
// char16_t
TEST_NUMERIC_LIMITS(char16_t)
TEST_NUMERIC_LIMITS(const char16_t)
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp
index 8deb28d3fd9c..8a3ca008db09 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/denorm_min.pass.cpp
@@ -15,6 +15,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -32,6 +34,9 @@ int main()
test<signed char>(0);
test<unsigned char>(0);
test<wchar_t>(0);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/digits.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/digits.pass.cpp
index 2dfea084b11d..7dec03d08613 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/digits.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/digits.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 7>();
test<unsigned char, 8>();
test<wchar_t, std::numeric_limits<wchar_t>::is_signed ? sizeof(wchar_t)*8-1 : sizeof(wchar_t)*8>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 8>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 16>();
test<char32_t, 32>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/digits10.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/digits10.pass.cpp
index 2c5302cd6334..017f8630af04 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/digits10.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/digits10.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -35,6 +37,9 @@ int main()
test<signed char, 2>();
test<unsigned char, 2>();
test<wchar_t, 5*sizeof(wchar_t)/2-1>(); // 4 -> 9 and 2 -> 4
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 2>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 4>();
test<char32_t, 9>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/epsilon.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/epsilon.pass.cpp
index 0cce4848187d..b27f5c583e8b 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/epsilon.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/epsilon.pass.cpp
@@ -15,6 +15,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -32,6 +34,9 @@ int main()
test<signed char>(0);
test<unsigned char>(0);
test<wchar_t>(0);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm.pass.cpp
index e61802054d18..5096ad211c41 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, std::float_denorm_style expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, std::denorm_absent>();
test<unsigned char, std::denorm_absent>();
test<wchar_t, std::denorm_absent>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, std::denorm_absent>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, std::denorm_absent>();
test<char32_t, std::denorm_absent>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm_loss.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm_loss.pass.cpp
index 660ecf5036d3..1b087f0cda4a 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm_loss.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/has_denorm_loss.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/has_infinity.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/has_infinity.pass.cpp
index f8ca2059d46a..1391f2096eff 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/has_infinity.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/has_infinity.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/has_quiet_NaN.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/has_quiet_NaN.pass.cpp
index 7592171695fb..cb5736f5c517 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/has_quiet_NaN.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/has_quiet_NaN.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/has_signaling_NaN.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/has_signaling_NaN.pass.cpp
index d68cd5d78878..4f43a6532b7a 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/has_signaling_NaN.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/has_signaling_NaN.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
index 033ecdc31af0..241f9cc27249 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
@@ -15,6 +15,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -34,6 +36,9 @@ int main()
test<signed char>(0);
test<unsigned char>(0);
test<wchar_t>(0);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_bounded.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_bounded.pass.cpp
index fa714d5d1506..e00afa900cc5 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_bounded.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_bounded.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, true>();
test<unsigned char, true>();
test<wchar_t, true>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, true>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, true>();
test<char32_t, true>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_exact.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_exact.pass.cpp
index b96a0e7fc5f5..8431b733f564 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_exact.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_exact.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, true>();
test<unsigned char, true>();
test<wchar_t, true>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, true>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, true>();
test<char32_t, true>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_iec559.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_iec559.pass.cpp
index 4408714c1a1d..2e9ac223a396 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_iec559.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_iec559.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_integer.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_integer.pass.cpp
index 79bc5867ec63..6e321d1ef24b 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_integer.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_integer.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, true>();
test<unsigned char, true>();
test<wchar_t, true>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, true>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, true>();
test<char32_t, true>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_modulo.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_modulo.pass.cpp
index 6a609963d04c..f6412a97d6e7 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_modulo.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_modulo.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, true>();
// test<wchar_t, false>(); // don't know
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, true>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, true>();
test<char32_t, true>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/is_signed.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/is_signed.pass.cpp
index 28570fd22790..b7a892605c36 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/is_signed.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/is_signed.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, true>();
test<unsigned char, false>();
test<wchar_t, wchar_t(-1) < wchar_t(0)>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/lowest.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/lowest.pass.cpp
index 21090aa9c4c1..f505f4142153 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/lowest.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/lowest.pass.cpp
@@ -17,6 +17,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -38,6 +40,9 @@ int main()
test<signed char>(SCHAR_MIN);
test<unsigned char>(0);
test<wchar_t>(WCHAR_MIN);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/max.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/max.pass.cpp
index 7517aaa192c1..65d5150a7b60 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/max.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/max.pass.cpp
@@ -17,6 +17,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -38,6 +40,9 @@ int main()
test<signed char>(SCHAR_MAX);
test<unsigned char>(UCHAR_MAX);
test<wchar_t>(WCHAR_MAX);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(UCHAR_MAX); // ??
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(USHRT_MAX);
test<char32_t>(UINT_MAX);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/max_digits10.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/max_digits10.pass.cpp
index de771ebe3b42..158e2791f92a 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/max_digits10.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/max_digits10.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 0>();
test<unsigned char, 0>();
test<wchar_t, 0>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 0>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 0>();
test<char32_t, 0>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent.pass.cpp
index 6b61f7ba4331..649310938600 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 0>();
test<unsigned char, 0>();
test<wchar_t, 0>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 0>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 0>();
test<char32_t, 0>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent10.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent10.pass.cpp
index 927585e9468b..c4c7a30a7e88 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent10.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/max_exponent10.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 0>();
test<unsigned char, 0>();
test<wchar_t, 0>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 0>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 0>();
test<char32_t, 0>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/min.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/min.pass.cpp
index e72fbba10512..a1e61fcdcaa5 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/min.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/min.pass.cpp
@@ -17,6 +17,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -38,6 +40,9 @@ int main()
test<signed char>(SCHAR_MIN);
test<unsigned char>(0);
test<wchar_t>(WCHAR_MIN);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent.pass.cpp
index 245e8441499d..930d01102700 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 0>();
test<unsigned char, 0>();
test<wchar_t, 0>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 0>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 0>();
test<char32_t, 0>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent10.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent10.pass.cpp
index b54d46fd52e8..05891b1f6f08 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent10.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/min_exponent10.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 0>();
test<unsigned char, 0>();
test<wchar_t, 0>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 0>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 0>();
test<char32_t, 0>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/quiet_NaN.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/quiet_NaN.pass.cpp
index 97166f0c3209..5d5597c47bc8 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/quiet_NaN.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/quiet_NaN.pass.cpp
@@ -16,6 +16,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test_imp(std::true_type)
@@ -51,6 +53,9 @@ int main()
test<signed char>();
test<unsigned char>();
test<wchar_t>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>();
test<char32_t>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/radix.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/radix.pass.cpp
index 98a2a53d192e..1514ae8411d8 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/radix.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/radix.pass.cpp
@@ -14,6 +14,8 @@
#include <limits>
#include <cfloat>
+#include "test_macros.h"
+
template <class T, int expected>
void
test()
@@ -31,6 +33,9 @@ int main()
test<signed char, 2>();
test<unsigned char, 2>();
test<wchar_t, 2>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, 2>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, 2>();
test<char32_t, 2>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/round_error.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/round_error.pass.cpp
index 5da5c9513a86..3c2dc5493e23 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/round_error.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/round_error.pass.cpp
@@ -15,6 +15,8 @@
#include <cfloat>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test(T expected)
@@ -32,6 +34,9 @@ int main()
test<signed char>(0);
test<unsigned char>(0);
test<wchar_t>(0);
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>(0);
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>(0);
test<char32_t>(0);
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/round_style.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/round_style.pass.cpp
index 645f6f7df76a..f1fd20035fbf 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/round_style.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/round_style.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, std::float_round_style expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, std::round_toward_zero>();
test<unsigned char, std::round_toward_zero>();
test<wchar_t, std::round_toward_zero>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, std::round_toward_zero>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, std::round_toward_zero>();
test<char32_t, std::round_toward_zero>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/signaling_NaN.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/signaling_NaN.pass.cpp
index d9df999ddb70..a0a6d7f844c6 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/signaling_NaN.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/signaling_NaN.pass.cpp
@@ -16,6 +16,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
void
test_imp(std::true_type)
@@ -51,6 +53,9 @@ int main()
test<signed char>();
test<unsigned char>();
test<wchar_t>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>();
test<char32_t>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp
index 9e2a8431a4e0..901eea4d0548 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/tinyness_before.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
template <class T, bool expected>
void
test()
@@ -30,6 +32,9 @@ int main()
test<signed char, false>();
test<unsigned char, false>();
test<wchar_t, false>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, false>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, false>();
test<char32_t, false>();
diff --git a/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp b/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
index 23811fada5e2..8e407c225e38 100644
--- a/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
+++ b/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
@@ -13,6 +13,8 @@
#include <limits>
+#include "test_macros.h"
+
#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__) || \
defined(__wasm__)
static const bool integral_types_trap = true;
@@ -37,6 +39,9 @@ int main()
test<signed char, integral_types_trap>();
test<unsigned char, integral_types_trap>();
test<wchar_t, integral_types_trap>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+ test<char8_t, integral_types_trap>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t, integral_types_trap>();
test<char32_t, integral_types_trap>();
diff --git a/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp
new file mode 100644
index 000000000000..36f82c0b75ed
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <algorithm>
+
+// Test the feature test macros defined by <algorithm>
+
+/* Constant Value
+ __cpp_lib_clamp 201603L [C++17]
+ __cpp_lib_constexpr_swap_algorithms 201806L [C++2a]
+ __cpp_lib_parallel_algorithm 201603L [C++17]
+ __cpp_lib_ranges 201811L [C++2a]
+ __cpp_lib_robust_nonmodifying_seq_ops 201304L [C++14]
+ __cpp_lib_sample 201603L [C++17]
+*/
+
+#include <algorithm>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_clamp
+# error "__cpp_lib_clamp should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_sample
+# error "__cpp_lib_sample should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_clamp
+# error "__cpp_lib_clamp should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_sample
+# error "__cpp_lib_sample should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++17"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++17"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_sample
+# error "__cpp_lib_sample should be defined in c++17"
+# endif
+# if __cpp_lib_sample != 201603L
+# error "__cpp_lib_sample should have the value 201603L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++2a"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_swap_algorithms != 201806L
+# error "__cpp_lib_constexpr_swap_algorithms should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++2a"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_ranges
+# error "__cpp_lib_ranges should be defined in c++2a"
+# endif
+# if __cpp_lib_ranges != 201811L
+# error "__cpp_lib_ranges should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++2a"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_sample
+# error "__cpp_lib_sample should be defined in c++2a"
+# endif
+# if __cpp_lib_sample != 201603L
+# error "__cpp_lib_sample should have the value 201603L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp
new file mode 100644
index 000000000000..dbd27c14b47c
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <any>
+
+// Test the feature test macros defined by <any>
+
+/* Constant Value
+ __cpp_lib_any 201606L [C++17]
+*/
+
+#include <any>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_any
+# error "__cpp_lib_any should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_any
+# error "__cpp_lib_any should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++17"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++2a"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp
new file mode 100644
index 000000000000..9d746ece9210
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <array>
+
+// Test the feature test macros defined by <array>
+
+/* Constant Value
+ __cpp_lib_array_constexpr 201603L [C++17]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <array>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++17"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++2a"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp
new file mode 100644
index 000000000000..835e48d0e7d8
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <atomic>
+
+// Test the feature test macros defined by <atomic>
+
+/* Constant Value
+ __cpp_lib_atomic_is_always_lock_free 201603L [C++17]
+ __cpp_lib_atomic_ref 201806L [C++2a]
+ __cpp_lib_char8_t 201811L [C++2a]
+*/
+
+#include <atomic>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17"
+# endif
+# if __cpp_lib_atomic_is_always_lock_free != 201603L
+# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++2a"
+# endif
+# if __cpp_lib_atomic_is_always_lock_free != 201603L
+# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should be defined in c++2a"
+# endif
+# if __cpp_lib_atomic_ref != 201806L
+# error "__cpp_lib_atomic_ref should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp
new file mode 100644
index 000000000000..97d2b9246bd5
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <bit>
+
+// Test the feature test macros defined by <bit>
+
+/* Constant Value
+ __cpp_lib_bit_cast 201806L [C++2a]
+*/
+
+#include <bit>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should be defined in c++2a"
+# endif
+# if __cpp_lib_bit_cast != 201806L
+# error "__cpp_lib_bit_cast should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp b/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp
new file mode 100644
index 000000000000..f1e252f8e86a
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// <charconv> feature macros
+
+/* Constant Value
+ __cpp_lib_to_chars 201611L
+
+*/
+
+#include <charconv>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <utility> are defined.
+
+/*
+#if !defined(__cpp_lib_fooby)
+# error "__cpp_lib_fooby is not defined"
+#elif __cpp_lib_fooby < 201606L
+# error "__cpp_lib_fooby has an invalid value"
+#endif
+*/
+}
diff --git a/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp
new file mode 100644
index 000000000000..3605878c55b9
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <chrono>
+
+// Test the feature test macros defined by <chrono>
+
+/* Constant Value
+ __cpp_lib_chrono 201611L [C++17]
+ __cpp_lib_chrono_udls 201304L [C++14]
+*/
+
+#include <chrono>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_chrono
+# error "__cpp_lib_chrono should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_chrono
+# error "__cpp_lib_chrono should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++14"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_chrono
+# error "__cpp_lib_chrono should be defined in c++17"
+# endif
+# if __cpp_lib_chrono != 201611L
+# error "__cpp_lib_chrono should have the value 201611L in c++17"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++17"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_chrono
+# error "__cpp_lib_chrono should be defined in c++2a"
+# endif
+# if __cpp_lib_chrono != 201611L
+# error "__cpp_lib_chrono should have the value 201611L in c++2a"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp
new file mode 100644
index 000000000000..13d6b9312d52
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <cmath>
+
+// Test the feature test macros defined by <cmath>
+
+/* Constant Value
+ __cpp_lib_hypot 201603L [C++17]
+ __cpp_lib_math_special_functions 201603L [C++17]
+*/
+
+#include <cmath>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_hypot
+# error "__cpp_lib_hypot should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_hypot
+# error "__cpp_lib_hypot should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_hypot
+# error "__cpp_lib_hypot should be defined in c++17"
+# endif
+# if __cpp_lib_hypot != 201603L
+# error "__cpp_lib_hypot should have the value 201603L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should be defined in c++17"
+# endif
+# if __cpp_lib_math_special_functions != 201603L
+# error "__cpp_lib_math_special_functions should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_hypot
+# error "__cpp_lib_hypot should be defined in c++2a"
+# endif
+# if __cpp_lib_hypot != 201603L
+# error "__cpp_lib_hypot should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should be defined in c++2a"
+# endif
+# if __cpp_lib_math_special_functions != 201603L
+# error "__cpp_lib_math_special_functions should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp
new file mode 100644
index 000000000000..c1dff02d24ee
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <compare>
+
+// Test the feature test macros defined by <compare>
+
+/* Constant Value
+ __cpp_lib_three_way_comparison 201711L [C++2a]
+*/
+
+#include <compare>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should be defined in c++2a"
+# endif
+# if __cpp_lib_three_way_comparison != 201711L
+# error "__cpp_lib_three_way_comparison should have the value 201711L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp
new file mode 100644
index 000000000000..170a3da8947e
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <complex>
+
+// Test the feature test macros defined by <complex>
+
+/* Constant Value
+ __cpp_lib_complex_udls 201309L [C++14]
+*/
+
+#include <complex>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++14"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++17"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp
new file mode 100644
index 000000000000..b212391227aa
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp
@@ -0,0 +1,34 @@
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// <concepts> feature macros
+
+/* Constant Value
+ __cpp_lib_concepts 201806L
+
+*/
+
+// XFAIL
+// #include <concepts>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <concepts> are defined.
+
+/*
+#if !defined(__cpp_lib_fooby)
+# error "__cpp_lib_fooby is not defined"
+#elif __cpp_lib_fooby < 201606L
+# error "__cpp_lib_fooby has an invalid value"
+#endif
+*/
+}
diff --git a/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp
new file mode 100644
index 000000000000..f4ebc8e10af2
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <cstddef>
+
+// Test the feature test macros defined by <cstddef>
+
+/* Constant Value
+ __cpp_lib_byte 201603L [C++17]
+*/
+
+#include <cstddef>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_byte
+# error "__cpp_lib_byte should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_byte
+# error "__cpp_lib_byte should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_byte
+# error "__cpp_lib_byte should be defined in c++17"
+# endif
+# if __cpp_lib_byte != 201603L
+# error "__cpp_lib_byte should have the value 201603L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_byte
+# error "__cpp_lib_byte should be defined in c++2a"
+# endif
+# if __cpp_lib_byte != 201603L
+# error "__cpp_lib_byte should have the value 201603L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp
new file mode 100644
index 000000000000..a325d6a3a2ad
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <deque>
+
+// Test the feature test macros defined by <deque>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <deque>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp
new file mode 100644
index 000000000000..97ce6d330d55
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <exception>
+
+// Test the feature test macros defined by <exception>
+
+/* Constant Value
+ __cpp_lib_uncaught_exceptions 201411L [C++17]
+*/
+
+#include <exception>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should be defined in c++17"
+# endif
+# if __cpp_lib_uncaught_exceptions != 201411L
+# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should be defined in c++2a"
+# endif
+# if __cpp_lib_uncaught_exceptions != 201411L
+# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp
new file mode 100644
index 000000000000..2fcd44cd079e
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp
@@ -0,0 +1,34 @@
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// <execution> feature macros
+
+/* Constant Value
+ __cpp_lib_execution 201603L
+
+*/
+
+// XFAIL
+// #include <execution>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <execution> are defined.
+
+/*
+#if !defined(__cpp_lib_fooby)
+# error "__cpp_lib_fooby is not defined"
+#elif __cpp_lib_fooby < 201606L
+# error "__cpp_lib_fooby has an invalid value"
+#endif
+*/
+}
diff --git a/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp
new file mode 100644
index 000000000000..990e5683b4b7
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <filesystem>
+
+// Test the feature test macros defined by <filesystem>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+ __cpp_lib_filesystem 201703L [C++17]
+*/
+
+#include <filesystem>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should be defined in c++17"
+# endif
+# if __cpp_lib_filesystem != 201703L
+# error "__cpp_lib_filesystem should have the value 201703L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should be defined in c++2a"
+# endif
+# if __cpp_lib_filesystem != 201703L
+# error "__cpp_lib_filesystem should have the value 201703L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp
new file mode 100644
index 000000000000..5bf0213078d6
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <forward_list>
+
+// Test the feature test macros defined by <forward_list>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_incomplete_container_elements 201505L [C++17]
+ __cpp_lib_list_remove_return_type 201806L [C++2a]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <forward_list>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++17"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++2a"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should be defined in c++2a"
+# endif
+# if __cpp_lib_list_remove_return_type != 201806L
+# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp
new file mode 100644
index 000000000000..5ca84c1cc5a3
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp
@@ -0,0 +1,245 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <functional>
+
+// Test the feature test macros defined by <functional>
+
+/* Constant Value
+ __cpp_lib_bind_front 201811L [C++2a]
+ __cpp_lib_boyer_moore_searcher 201603L [C++17]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_invoke 201411L [C++17]
+ __cpp_lib_not_fn 201603L [C++17]
+ __cpp_lib_ranges 201811L [C++2a]
+ __cpp_lib_result_of_sfinae 201210L [C++14]
+ __cpp_lib_transparent_operators 201210L [C++14]
+ 201510L [C++17]
+*/
+
+#include <functional>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_invoke
+# error "__cpp_lib_invoke should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_invoke
+# error "__cpp_lib_invoke should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++14"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++14"
+# endif
+# if __cpp_lib_transparent_operators != 201210L
+# error "__cpp_lib_transparent_operators should have the value 201210L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
+# endif
+# if __cpp_lib_boyer_moore_searcher != 201603L
+# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_invoke
+# error "__cpp_lib_invoke should be defined in c++17"
+# endif
+# if __cpp_lib_invoke != 201411L
+# error "__cpp_lib_invoke should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should be defined in c++17"
+# endif
+# if __cpp_lib_not_fn != 201603L
+# error "__cpp_lib_not_fn should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++17"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++17"
+# endif
+# if __cpp_lib_transparent_operators != 201510L
+# error "__cpp_lib_transparent_operators should have the value 201510L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should be defined in c++2a"
+# endif
+# if __cpp_lib_bind_front != 201811L
+# error "__cpp_lib_bind_front should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should be defined in c++2a"
+# endif
+# if __cpp_lib_boyer_moore_searcher != 201603L
+# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_invoke
+# error "__cpp_lib_invoke should be defined in c++2a"
+# endif
+# if __cpp_lib_invoke != 201411L
+# error "__cpp_lib_invoke should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should be defined in c++2a"
+# endif
+# if __cpp_lib_not_fn != 201603L
+# error "__cpp_lib_not_fn should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_ranges
+# error "__cpp_lib_ranges should be defined in c++2a"
+# endif
+# if __cpp_lib_ranges != 201811L
+# error "__cpp_lib_ranges should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++2a"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++2a"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++2a"
+# endif
+# if __cpp_lib_transparent_operators != 201510L
+# error "__cpp_lib_transparent_operators should have the value 201510L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py b/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py
new file mode 100755
index 000000000000..c80ebb11e679
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py
@@ -0,0 +1,977 @@
+#!/usr/bin/env python
+
+import os
+import tempfile
+
+def get_libcxx_paths():
+ script_path = os.path.dirname(os.path.abspath(__file__))
+ script_name = os.path.basename(__file__)
+ assert os.path.exists(script_path)
+ depth = 5
+ src_root = script_path
+ for _ in xrange(0, 5):
+ src_root = os.path.dirname(src_root)
+ include_path = os.path.join(src_root, 'include')
+ assert os.path.exists(include_path)
+ docs_path = os.path.join(src_root, 'docs')
+ assert os.path.exists(docs_path)
+ return script_path, script_name, src_root, include_path, docs_path
+
+
+script_path, script_name, source_root, include_path, docs_path = get_libcxx_paths()
+
+def has_header(h):
+ h_path = os.path.join(include_path, h)
+ return os.path.exists(h_path)
+
+def add_version_header(tc):
+ tc["headers"].append("version")
+ return tc
+
+feature_test_macros = sorted([ add_version_header(x) for x in [
+ # C++14 macros
+ {"name": "__cpp_lib_integer_sequence",
+ "values": {
+ "c++14": 201304L
+ },
+ "headers": ["utility"],
+ },
+ {"name": "__cpp_lib_exchange_function",
+ "values": {
+ "c++14": 201304L
+ },
+ "headers": ["utility"],
+ },
+ {"name": "__cpp_lib_tuples_by_type",
+ "values": {
+ "c++14": 201304L
+ },
+ "headers": ["utility", "tuple"],
+ },
+ {"name": "__cpp_lib_tuple_element_t",
+ "values": {
+ "c++14": 201402L
+ },
+ "headers": ["tuple"],
+ },
+ {"name": "__cpp_lib_make_unique",
+ "values": {
+ "c++14": 201304L
+ },
+ "headers": ["memory"],
+ },
+ {"name": "__cpp_lib_transparent_operators",
+ "values": {
+ "c++14": 201210L,
+ "c++17": 201510L,
+ },
+ "headers": ["functional"],
+ },
+ {"name": "__cpp_lib_integral_constant_callable",
+ "values": {
+ "c++14": 201304L
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_transformation_trait_aliases",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["type_traits"]
+ },
+ {"name": "__cpp_lib_result_of_sfinae",
+ "values": {
+ "c++14": 201210L,
+ },
+ "headers": ["functional", "type_traits"]
+ },
+ {"name": "__cpp_lib_is_final",
+ "values": {
+ "c++14": 201402L,
+ },
+ "headers": ["type_traits"]
+ },
+ {"name": "__cpp_lib_is_null_pointer",
+ "values": {
+ "c++14": 201309L,
+ },
+ "headers": ["type_traits"]
+ },
+ {"name": "__cpp_lib_chrono_udls",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["chrono"]
+ },
+ {"name": "__cpp_lib_string_udls",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["string"]
+ },
+ {"name": "__cpp_lib_generic_associative_lookup",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["map", "set"]
+ },
+ {"name": "__cpp_lib_null_iterators",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["iterator"]
+ },
+ {"name": "__cpp_lib_make_reverse_iterator",
+ "values": {
+ "c++14": 201402L,
+ },
+ "headers": ["iterator"]
+ },
+ {"name": "__cpp_lib_robust_nonmodifying_seq_ops",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["algorithm"]
+ },
+ {"name": "__cpp_lib_complex_udls",
+ "values": {
+ "c++14": 201309L,
+ },
+ "headers": ["complex"]
+ },
+ {"name": "__cpp_lib_quoted_string_io",
+ "values": {
+ "c++14": 201304L,
+ },
+ "headers": ["iomanip"]
+ },
+ {"name": "__cpp_lib_shared_timed_mutex",
+ "values": {
+ "c++14": 201402L,
+ },
+ "headers": ["shared_mutex"],
+ "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ },
+ # C++17 macros
+ {"name": "__cpp_lib_atomic_is_always_lock_free",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["atomic"],
+ "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ },
+ {"name": "__cpp_lib_filesystem",
+ "values": {
+ "c++17": 201703L,
+ },
+ "headers": ["filesystem"]
+ },
+ {"name": "__cpp_lib_invoke",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["functional"]
+ },
+ {"name": "__cpp_lib_void_t",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["type_traits"]
+ },
+ {"name": "__cpp_lib_node_extract",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["map", "set", "unordered_map", "unordered_set"]
+ },
+ {"name": "__cpp_lib_byte",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["cstddef"],
+ },
+ {"name": "__cpp_lib_hardware_interference_size",
+ "values": {
+ "c++17": 201703L,
+ },
+ "headers": ["new"],
+ },
+ {"name": "__cpp_lib_launder",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["new"],
+ },
+ {"name": "__cpp_lib_uncaught_exceptions",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["exception"],
+ },
+ {"name": "__cpp_lib_as_const",
+ "values": {
+ "c++17": 201510L,
+ },
+ "headers": ["utility"],
+ },
+ {"name": "__cpp_lib_make_from_tuple",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["tuple"],
+ },
+ {"name": "__cpp_lib_apply",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["tuple"],
+ },
+ {"name": "__cpp_lib_optional",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["optional"],
+ },
+ {"name": "__cpp_lib_variant",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["variant"],
+ },
+ {"name": "__cpp_lib_any",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["any"],
+ },
+ {"name": "__cpp_lib_addressof_constexpr",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["memory"],
+ "depends": "TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)",
+ },
+ {"name": "__cpp_lib_raw_memory_algorithms",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["memory"],
+ },
+ {"name": "__cpp_lib_enable_shared_from_this",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["memory"],
+ },
+ {"name": "__cpp_lib_shared_ptr_weak_type",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["memory"],
+ },
+ {"name": "__cpp_lib_shared_ptr_arrays",
+ "values": {
+ "c++17": 201611L,
+ },
+ "headers": ["memory"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_memory_resource",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["memory_resource"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_boyer_moore_searcher",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["functional"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_not_fn",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["functional"],
+ },
+ {"name": "__cpp_lib_bool_constant",
+ "values": {
+ "c++17": 201505L,
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_type_trait_variable_templates",
+ "values": {
+ "c++17": 201510L,
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_logical_traits",
+ "values": {
+ "c++17": 201510L,
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_is_swappable",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_is_invocable",
+ "values": {
+ "c++17": 201703L,
+ },
+ "headers": ["type_traits"],
+ },
+ {"name": "__cpp_lib_has_unique_object_representations",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["type_traits"],
+ "depends": "TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700",
+ "internal_depends": "defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)",
+ },
+ {"name": "__cpp_lib_is_aggregate",
+ "values": {
+ "c++17": 201703L,
+ },
+ "headers": ["type_traits"],
+ "depends": "TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_IS_AGGREGATE)",
+ },
+ {"name": "__cpp_lib_chrono",
+ "values": {
+ "c++17": 201611L,
+ },
+ "headers": ["chrono"],
+ },
+ {"name": "__cpp_lib_execution",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["execution"],
+ "unimplemented": True
+ },
+ {"name": "__cpp_lib_parallel_algorithm",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["algorithm", "numeric"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_to_chars",
+ "values": {
+ "c++17": 201611L,
+ },
+ "headers": ["utility"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_string_view",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["string", "string_view"],
+ },
+ {"name": "__cpp_lib_allocator_traits_is_always_equal",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["memory", "scoped_allocator", "string", "deque", "forward_list", "list", "vector", "map", "set", "unordered_map", "unordered_set"],
+ },
+ {"name": "__cpp_lib_incomplete_container_elements",
+ "values": {
+ "c++17": 201505L,
+ },
+ "headers": ["forward_list", "list", "vector"],
+ },
+ {"name": "__cpp_lib_map_try_emplace",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["map"],
+ },
+ {"name": "__cpp_lib_unordered_map_try_emplace",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["unordered_map"],
+ },
+ {"name": "__cpp_lib_array_constexpr",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["iterator", "array"],
+ },
+ {"name": "__cpp_lib_nonmember_container_access",
+ "values": {
+ "c++17": 201411L,
+ },
+ "headers": ["iterator", "array", "deque", "forward_list", "list", "map", "regex",
+ "set", "string", "unordered_map", "unordered_set", "vector"],
+ },
+ {"name": "__cpp_lib_sample",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["algorithm"],
+ },
+ {"name": "__cpp_lib_clamp",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["algorithm"],
+ },
+ {"name": "__cpp_lib_gcd_lcm",
+ "values": {
+ "c++17": 201606L,
+ },
+ "headers": ["numeric"],
+ },
+ {"name": "__cpp_lib_hypot",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["cmath"],
+ },
+ {"name": "__cpp_lib_math_special_functions",
+ "values": {
+ "c++17": 201603L,
+ },
+ "headers": ["cmath"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_shared_mutex",
+ "values": {
+ "c++17": 201505L,
+ },
+ "headers": ["shared_mutex"],
+ "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ },
+ {"name": "__cpp_lib_scoped_lock",
+ "values": {
+ "c++17": 201703L,
+ },
+ "headers": ["mutex"],
+ },
+ # C++2a
+ {"name": "__cpp_lib_char8_t",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["atomic", "filesystem", "istream", "limits", "locale", "ostream",
+ "string", "string_view"],
+ "depends": "defined(__cpp_char8_t)",
+ "internal_depends": "!defined(_LIBCPP_NO_HAS_CHAR8_T)",
+ },
+ {"name": "__cpp_lib_erase_if",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["string", "deque", "forward_list", "list", "vector", "map",
+ "set", "unordered_map", "unordered_set"]
+ },
+ {"name": "__cpp_lib_destroying_delete",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["new"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_three_way_comparison",
+ "values": {
+ "c++2a": 201711L,
+ },
+ "headers": ["compare"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_concepts",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["concepts"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_constexpr_swap_algorithms",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["algorithm"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_constexpr_misc",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["array", "functional", "iterator", "string_view", "tuple", "utility"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_bind_front",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["functional"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_is_constant_evaluated",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["type_traits"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_list_remove_return_type",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["forward_list", "list"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_generic_unordered_lookup",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["unordered_map", "unordered_set"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_ranges",
+ "values": {
+ "c++2a": 201811L,
+ },
+ "headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_bit_cast",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["bit"],
+ "unimplemented": True,
+ },
+ {"name": "__cpp_lib_atomic_ref",
+ "values": {
+ "c++2a": 201806L,
+ },
+ "headers": ["atomic"],
+ "unimplemented": True,
+ "depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ "internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
+ },
+]], key=lambda tc: tc["name"])
+
+def get_std_dialects():
+ std_dialects = ['c++14', 'c++17', 'c++2a']
+ return list(std_dialects)
+
+def get_first_std(d):
+ for s in get_std_dialects():
+ if s in d.keys():
+ return s
+ return None
+
+def get_last_std(d):
+ rev_dialects = get_std_dialects()
+ rev_dialects.reverse()
+ for s in rev_dialects:
+ if s in d.keys():
+ return s
+ return None
+
+def get_std_before(d, std):
+ std_dialects = get_std_dialects()
+ candidates = std_dialects[0:std_dialects.index(std)]
+ candidates.reverse()
+ for cand in candidates:
+ if cand in d.keys():
+ return cand
+ return None
+
+def get_value_before(d, std):
+ new_std = get_std_before(d, std)
+ if new_std is None:
+ return None
+ return d[new_std]
+
+def get_for_std(d, std):
+ # This catches the C++11 case for which there should be no defined feature
+ # test macros.
+ std_dialects = get_std_dialects()
+ if std not in std_dialects:
+ return None
+ # Find the value for the newest C++ dialect between C++14 and std
+ std_list = list(std_dialects[0:std_dialects.index(std)+1])
+ std_list.reverse()
+ for s in std_list:
+ if s in d.keys():
+ return d[s]
+ return None
+
+
+"""
+ Functions to produce the <version> header
+"""
+
+def produce_macros_definition_for_std(std):
+ result = ""
+ indent = 56
+ for tc in feature_test_macros:
+ if std not in tc["values"]:
+ continue
+ inner_indent = 1
+ if 'depends' in tc.keys():
+ assert 'internal_depends' in tc.keys()
+ result += "# if %s\n" % tc["internal_depends"]
+ inner_indent += 2
+ if get_value_before(tc["values"], std) is not None:
+ assert 'depends' not in tc.keys()
+ result += "# undef %s\n" % tc["name"]
+ line = "#%sdefine %s" % ((" " * inner_indent), tc["name"])
+ line += " " * (indent - len(line))
+ line += "%sL" % tc["values"][std]
+ if 'unimplemented' in tc.keys():
+ line = "// " + line
+ result += line
+ result += "\n"
+ if 'depends' in tc.keys():
+ result += "# endif\n"
+ return result
+
+def chunks(l, n):
+ """Yield successive n-sized chunks from l."""
+ for i in range(0, len(l), n):
+ yield l[i:i + n]
+
+def produce_version_synopsis():
+ indent = 56
+ header_indent = 56 + len("20XXYYL ")
+ result = ""
+ def indent_to(s, val):
+ if len(s) >= val:
+ return s
+ s += " " * (val - len(s))
+ return s
+ line = indent_to("Macro name", indent) + "Value"
+ line = indent_to(line, header_indent) + "Headers"
+ result += line + "\n"
+ for tc in feature_test_macros:
+ prev_defined_std = get_last_std(tc["values"])
+ line = "{name: <{indent}}{value}L ".format(name=tc['name'], indent=indent,
+ value=tc["values"][prev_defined_std])
+ headers = list(tc["headers"])
+ headers.remove("version")
+ for chunk in chunks(headers, 3):
+ line = indent_to(line, header_indent)
+ chunk = ['<%s>' % header for header in chunk]
+ line += ' '.join(chunk)
+ result += line
+ result += "\n"
+ line = ""
+ while True:
+ prev_defined_std = get_std_before(tc["values"], prev_defined_std)
+ if prev_defined_std is None:
+ break
+ result += "%s%sL // %s\n" % (indent_to("", indent), tc["values"][prev_defined_std],
+ prev_defined_std.replace("c++", "C++"))
+ return result
+
+
+def produce_version_header():
+ template="""// -*- C++ -*-
+//===--------------------------- version ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_VERSIONH
+#define _LIBCPP_VERSIONH
+
+/*
+ version synopsis
+
+{synopsis}
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 11
+{cxx14_macros}
+#endif
+
+#if _LIBCPP_STD_VER > 14
+{cxx17_macros}
+#endif
+
+#if _LIBCPP_STD_VER > 17
+{cxx2a_macros}
+#endif
+
+#endif // _LIBCPP_VERSIONH
+"""
+ return template.format(
+ synopsis=produce_version_synopsis().strip(),
+ cxx14_macros=produce_macros_definition_for_std('c++14').strip(),
+ cxx17_macros=produce_macros_definition_for_std('c++17').strip(),
+ cxx2a_macros=produce_macros_definition_for_std('c++2a').strip())
+
+"""
+ Functions to produce test files
+"""
+
+test_types = {
+ "undefined": """
+# ifdef {name}
+# error "{name} should not be defined before {std_first}"
+# endif
+""",
+
+ "depends": """
+# if {depends}
+# ifndef {name}
+# error "{name} should be defined in {std}"
+# endif
+# if {name} != {value}
+# error "{name} should have the value {value} in {std}"
+# endif
+# else
+# ifdef {name}
+# error "{name} should not be defined when {depends} is not defined!"
+# endif
+# endif
+""",
+
+ "unimplemented": """
+# if !defined(_LIBCPP_VERSION)
+# ifndef {name}
+# error "{name} should be defined in {std}"
+# endif
+# if {name} != {value}
+# error "{name} should have the value {value} in {std}"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef {name}
+# error "{name} should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+""",
+
+ "defined":"""
+# ifndef {name}
+# error "{name} should be defined in {std}"
+# endif
+# if {name} != {value}
+# error "{name} should have the value {value} in {std}"
+# endif
+"""
+}
+
+def generate_std_test(test_list, std):
+ result = ""
+ for tc in test_list:
+ val = get_for_std(tc["values"], std)
+ if val is not None:
+ val = "%sL" % val
+ if val is None:
+ result += test_types["undefined"].format(name=tc["name"], std_first=get_first_std(tc["values"]))
+ elif 'unimplemented' in tc.keys():
+ result += test_types["unimplemented"].format(name=tc["name"], value=val, std=std)
+ elif "depends" in tc.keys():
+ result += test_types["depends"].format(name=tc["name"], value=val, std=std, depends=tc["depends"])
+ else:
+ result += test_types["defined"].format(name=tc["name"], value=val, std=std)
+ return result
+
+def generate_synopsis(test_list):
+ max_name_len = max([len(tc["name"]) for tc in test_list])
+ indent = max_name_len + 8
+ def mk_line(prefix, suffix):
+ return "{prefix: <{max_len}}{suffix}\n".format(prefix=prefix, suffix=suffix,
+ max_len=indent)
+ result = ""
+ result += mk_line("/* Constant", "Value")
+ for tc in test_list:
+ prefix = " %s" % tc["name"]
+ for std in [s for s in get_std_dialects() if s in tc["values"].keys()]:
+ result += mk_line(prefix, "%sL [%s]" % (tc["values"][std], std.replace("c++", "C++")))
+ prefix = ""
+ result += "*/"
+ return result
+
+def is_threading_header_unsafe_to_include(h):
+ # NOTE: "<mutex>" does not blow up when included without threads.
+ return h in ['atomic', 'shared_mutex']
+
+def produce_tests():
+ headers = set([h for tc in feature_test_macros for h in tc["headers"]])
+ for h in headers:
+ test_list = [tc for tc in feature_test_macros if h in tc["headers"]]
+ if not has_header(h):
+ for tc in test_list:
+ assert 'unimplemented' in tc.keys()
+ continue
+ test_tags = ""
+ if is_threading_header_unsafe_to_include(h):
+ test_tags += '\n// UNSUPPORTED: libcpp-has-no-threads\n'
+ test_body = \
+"""//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by {script_name}
+// and should not be edited manually.
+{test_tags}
+// <{header}>
+
+// Test the feature test macros defined by <{header}>
+
+{synopsis}
+
+#include <{header}>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+{cxx11_tests}
+
+#elif TEST_STD_VER == 14
+
+{cxx14_tests}
+
+#elif TEST_STD_VER == 17
+
+{cxx17_tests}
+
+#elif TEST_STD_VER > 17
+
+{cxx2a_tests}
+
+#endif // TEST_STD_VER > 17
+
+int main() {{}}
+""".format(script_name=script_name,
+ header=h,
+ test_tags=test_tags,
+ synopsis=generate_synopsis(test_list),
+ cxx11_tests=generate_std_test(test_list, 'c++11').strip(),
+ cxx14_tests=generate_std_test(test_list, 'c++14').strip(),
+ cxx17_tests=generate_std_test(test_list, 'c++17').strip(),
+ cxx2a_tests=generate_std_test(test_list, 'c++2a').strip())
+ test_name = "{header}.version.pass.cpp".format(header=h)
+ out_path = os.path.join(script_path, test_name)
+ with open(out_path, 'w') as f:
+ f.write(test_body)
+
+"""
+ Produce documentation for the feature test macros
+"""
+
+def make_widths(grid):
+ widths = []
+ for i in range(0, len(grid[0])):
+ cell_width = 2 + max(reduce(lambda x,y: x+y, [[len(row[i])] for row in grid], []))
+ widths += [cell_width]
+ return widths
+
+def create_table(grid, indent):
+ indent_str = ' '*indent
+ col_widths = make_widths(grid)
+ num_cols = len(grid[0])
+ result = indent_str + add_divider(col_widths, 2)
+ header_flag = 2
+ for row_i in xrange(0, len(grid)):
+ row = grid[row_i]
+ result = result + indent_str + ' '.join([pad_cell(row[i], col_widths[i]) for i in range(0, len(row))]) + '\n'
+ is_cxx_header = row[0].startswith('**')
+ if row_i == len(grid) - 1:
+ header_flag = 2
+ result = result + indent_str + add_divider(col_widths, 1 if is_cxx_header else header_flag)
+ header_flag = 0
+ return result
+
+def add_divider(widths, header_flag):
+ if header_flag == 2:
+ return ' '.join(['='*w for w in widths]) + '\n'
+ if header_flag == 1:
+ return '-'.join(['-'*w for w in widths]) + '\n'
+ else:
+ return ' '.join(['-'*w for w in widths]) + '\n'
+
+def pad_cell(s, length, left_align=True):
+ padding = ((length - len(s)) * ' ')
+ return s + padding
+
+
+def get_status_table():
+ table = [["Macro Name", "Value"]]
+ for std in get_std_dialects():
+ table += [["**" + std.replace("c++", "C++ ") + "**", ""]]
+ for tc in feature_test_macros:
+ if std not in tc["values"].keys():
+ continue
+ value = "``%sL``" % tc["values"][std]
+ if 'unimplemented' in tc.keys():
+ value = '*unimplemented*'
+ table += [["``%s``" % tc["name"], value]]
+ return table
+
+def produce_docs():
+ doc_str = """.. _FeatureTestMacroTable:
+
+==========================
+Feature Test Macro Support
+==========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+This file documents the feature test macros currently supported by libc++.
+
+.. _feature-status:
+
+Status
+======
+
+.. table:: Current Status
+ :name: feature-status-table
+ :widths: auto
+
+{status_tables}
+
+""".format(status_tables=create_table(get_status_table(), 4))
+
+ table_doc_path = os.path.join(docs_path, 'FeatureTestMacroTable.rst')
+ with open(table_doc_path, 'w') as f:
+ f.write(doc_str)
+
+def main():
+ with tempfile.NamedTemporaryFile(mode='w', prefix='version.', delete=False) as tmp_file:
+ print("producing new <version> header as %s" % tmp_file.name)
+ tmp_file.write(produce_version_header())
+ produce_tests()
+ produce_docs()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
new file mode 100644
index 000000000000..ef2e058265cc
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <iomanip>
+
+// Test the feature test macros defined by <iomanip>
+
+/* Constant Value
+ __cpp_lib_quoted_string_io 201304L [C++14]
+*/
+
+#include <iomanip>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++14"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++17"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++2a"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
new file mode 100644
index 000000000000..77eec86cf7c8
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <istream>
+
+// Test the feature test macros defined by <istream>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+*/
+
+#include <istream>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
new file mode 100644
index 000000000000..7312c4de7b84
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
@@ -0,0 +1,183 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <iterator>
+
+// Test the feature test macros defined by <iterator>
+
+/* Constant Value
+ __cpp_lib_array_constexpr 201603L [C++17]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_make_reverse_iterator 201402L [C++14]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+ __cpp_lib_null_iterators 201304L [C++14]
+ __cpp_lib_ranges 201811L [C++2a]
+*/
+
+#include <iterator>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++14"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++14"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++17"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++17"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++17"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++2a"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++2a"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++2a"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_ranges
+# error "__cpp_lib_ranges should be defined in c++2a"
+# endif
+# if __cpp_lib_ranges != 201811L
+# error "__cpp_lib_ranges should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp
new file mode 100644
index 000000000000..e63df4ff5230
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <limits>
+
+// Test the feature test macros defined by <limits>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+*/
+
+#include <limits>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp
new file mode 100644
index 000000000000..cf087259fc8a
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <list>
+
+// Test the feature test macros defined by <list>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_incomplete_container_elements 201505L [C++17]
+ __cpp_lib_list_remove_return_type 201806L [C++2a]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <list>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++17"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++2a"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should be defined in c++2a"
+# endif
+# if __cpp_lib_list_remove_return_type != 201806L
+# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
new file mode 100644
index 000000000000..352d7363725e
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <locale>
+
+// Test the feature test macros defined by <locale>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+*/
+
+#include <locale>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp
new file mode 100644
index 000000000000..a98bc28c89cb
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <map>
+
+// Test the feature test macros defined by <map>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_generic_associative_lookup 201304L [C++14]
+ __cpp_lib_map_try_emplace 201411L [C++17]
+ __cpp_lib_node_extract 201606L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <map>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++14"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++17"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should be defined in c++17"
+# endif
+# if __cpp_lib_map_try_emplace != 201411L
+# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++17"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should be defined in c++2a"
+# endif
+# if __cpp_lib_map_try_emplace != 201411L
+# error "__cpp_lib_map_try_emplace should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++2a"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp
new file mode 100644
index 000000000000..1d8cb9005e4b
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp
@@ -0,0 +1,247 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <memory>
+
+// Test the feature test macros defined by <memory>
+
+/* Constant Value
+ __cpp_lib_addressof_constexpr 201603L [C++17]
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_enable_shared_from_this 201603L [C++17]
+ __cpp_lib_make_unique 201304L [C++14]
+ __cpp_lib_ranges 201811L [C++2a]
+ __cpp_lib_raw_memory_algorithms 201606L [C++17]
+ __cpp_lib_shared_ptr_arrays 201611L [C++17]
+ __cpp_lib_shared_ptr_weak_type 201606L [C++17]
+*/
+
+#include <memory>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++14"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# if TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should be defined in c++17"
+# endif
+# if __cpp_lib_addressof_constexpr != 201603L
+# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should be defined in c++17"
+# endif
+# if __cpp_lib_enable_shared_from_this != 201603L
+# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++17"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should be defined in c++17"
+# endif
+# if __cpp_lib_raw_memory_algorithms != 201606L
+# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should be defined in c++17"
+# endif
+# if __cpp_lib_shared_ptr_arrays != 201611L
+# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17"
+# endif
+# if __cpp_lib_shared_ptr_weak_type != 201606L
+# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should be defined in c++2a"
+# endif
+# if __cpp_lib_addressof_constexpr != 201603L
+# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should be defined in c++2a"
+# endif
+# if __cpp_lib_enable_shared_from_this != 201603L
+# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++2a"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_ranges
+# error "__cpp_lib_ranges should be defined in c++2a"
+# endif
+# if __cpp_lib_ranges != 201811L
+# error "__cpp_lib_ranges should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should be defined in c++2a"
+# endif
+# if __cpp_lib_raw_memory_algorithms != 201606L
+# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_ptr_arrays != 201611L
+# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_ptr_weak_type != 201606L
+# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp
new file mode 100644
index 000000000000..857ece267335
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp
@@ -0,0 +1,34 @@
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// <memory_resource> feature macros
+
+/* Constant Value
+ __cpp_lib_memory_resource 201603L
+
+*/
+
+// XFAIL
+// #include <memory_resource>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <memory_resource> are defined.
+
+/*
+#if !defined(__cpp_lib_fooby)
+# error "__cpp_lib_fooby is not defined"
+#elif __cpp_lib_fooby < 201606L
+# error "__cpp_lib_fooby has an invalid value"
+#endif
+*/
+}
diff --git a/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp
new file mode 100644
index 000000000000..04edd597b45e
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <mutex>
+
+// Test the feature test macros defined by <mutex>
+
+/* Constant Value
+ __cpp_lib_scoped_lock 201703L [C++17]
+*/
+
+#include <mutex>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should be defined in c++17"
+# endif
+# if __cpp_lib_scoped_lock != 201703L
+# error "__cpp_lib_scoped_lock should have the value 201703L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should be defined in c++2a"
+# endif
+# if __cpp_lib_scoped_lock != 201703L
+# error "__cpp_lib_scoped_lock should have the value 201703L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp
new file mode 100644
index 000000000000..e2dd9b774333
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <new>
+
+// Test the feature test macros defined by <new>
+
+/* Constant Value
+ __cpp_lib_destroying_delete 201806L [C++2a]
+ __cpp_lib_hardware_interference_size 201703L [C++17]
+ __cpp_lib_launder 201606L [C++17]
+*/
+
+#include <new>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_launder
+# error "__cpp_lib_launder should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_launder
+# error "__cpp_lib_launder should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should be defined in c++17"
+# endif
+# if __cpp_lib_hardware_interference_size != 201703L
+# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17"
+# endif
+
+# ifndef __cpp_lib_launder
+# error "__cpp_lib_launder should be defined in c++17"
+# endif
+# if __cpp_lib_launder != 201606L
+# error "__cpp_lib_launder should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should be defined in c++2a"
+# endif
+# if __cpp_lib_destroying_delete != 201806L
+# error "__cpp_lib_destroying_delete should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should be defined in c++2a"
+# endif
+# if __cpp_lib_hardware_interference_size != 201703L
+# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++2a"
+# endif
+
+# ifndef __cpp_lib_launder
+# error "__cpp_lib_launder should be defined in c++2a"
+# endif
+# if __cpp_lib_launder != 201606L
+# error "__cpp_lib_launder should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
new file mode 100644
index 000000000000..83b6207654f8
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <numeric>
+
+// Test the feature test macros defined by <numeric>
+
+/* Constant Value
+ __cpp_lib_gcd_lcm 201606L [C++17]
+ __cpp_lib_parallel_algorithm 201603L [C++17]
+*/
+
+#include <numeric>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should be defined in c++17"
+# endif
+# if __cpp_lib_gcd_lcm != 201606L
+# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++17"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should be defined in c++2a"
+# endif
+# if __cpp_lib_gcd_lcm != 201606L
+# error "__cpp_lib_gcd_lcm should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++2a"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp
new file mode 100644
index 000000000000..4c9fecd21134
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <optional>
+
+// Test the feature test macros defined by <optional>
+
+/* Constant Value
+ __cpp_lib_optional 201606L [C++17]
+*/
+
+#include <optional>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_optional
+# error "__cpp_lib_optional should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_optional
+# error "__cpp_lib_optional should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_optional
+# error "__cpp_lib_optional should be defined in c++17"
+# endif
+# if __cpp_lib_optional != 201606L
+# error "__cpp_lib_optional should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_optional
+# error "__cpp_lib_optional should be defined in c++2a"
+# endif
+# if __cpp_lib_optional != 201606L
+# error "__cpp_lib_optional should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
new file mode 100644
index 000000000000..1bcf8d55d480
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <ostream>
+
+// Test the feature test macros defined by <ostream>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+*/
+
+#include <ostream>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
new file mode 100644
index 000000000000..cd07ac06828e
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <regex>
+
+// Test the feature test macros defined by <regex>
+
+/* Constant Value
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <regex>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp
new file mode 100644
index 000000000000..4c2f35af95fc
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <scoped_allocator>
+
+// Test the feature test macros defined by <scoped_allocator>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+*/
+
+#include <scoped_allocator>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp
new file mode 100644
index 000000000000..7a4cabde8538
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <set>
+
+// Test the feature test macros defined by <set>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_generic_associative_lookup 201304L [C++14]
+ __cpp_lib_node_extract 201606L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <set>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++14"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++17"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++17"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++2a"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp
new file mode 100644
index 000000000000..493411ffddec
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// Test the feature test macros defined by <shared_mutex>
+
+/* Constant Value
+ __cpp_lib_shared_mutex 201505L [C++17]
+ __cpp_lib_shared_timed_mutex 201402L [C++14]
+*/
+
+#include <shared_mutex>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined before c++17"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++14"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 17
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should be defined in c++17"
+# endif
+# if __cpp_lib_shared_mutex != 201505L
+# error "__cpp_lib_shared_mutex should have the value 201505L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++17"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_mutex != 201505L
+# error "__cpp_lib_shared_mutex should have the value 201505L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
new file mode 100644
index 000000000000..8639c468cc36
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <string>
+
+// Test the feature test macros defined by <string>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_char8_t 201811L [C++2a]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+ __cpp_lib_string_udls 201304L [C++14]
+ __cpp_lib_string_view 201606L [C++17]
+*/
+
+#include <string>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++14"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++17"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++17"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++2a"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
new file mode 100644
index 000000000000..44e97f3af801
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <string_view>
+
+// Test the feature test macros defined by <string_view>
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L [C++2a]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_string_view 201606L [C++17]
+*/
+
+#include <string_view>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++17"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++2a"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
new file mode 100644
index 000000000000..6466a2f6458b
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <tuple>
+
+// Test the feature test macros defined by <tuple>
+
+/* Constant Value
+ __cpp_lib_apply 201603L [C++17]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_make_from_tuple 201606L [C++17]
+ __cpp_lib_tuple_element_t 201402L [C++14]
+ __cpp_lib_tuples_by_type 201304L [C++14]
+*/
+
+#include <tuple>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_apply
+# error "__cpp_lib_apply should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_apply
+# error "__cpp_lib_apply should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++14"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++14"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_apply
+# error "__cpp_lib_apply should be defined in c++17"
+# endif
+# if __cpp_lib_apply != 201603L
+# error "__cpp_lib_apply should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should be defined in c++17"
+# endif
+# if __cpp_lib_make_from_tuple != 201606L
+# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++17"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++17"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_apply
+# error "__cpp_lib_apply should be defined in c++2a"
+# endif
+# if __cpp_lib_apply != 201603L
+# error "__cpp_lib_apply should have the value 201603L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should be defined in c++2a"
+# endif
+# if __cpp_lib_make_from_tuple != 201606L
+# error "__cpp_lib_make_from_tuple should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++2a"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++2a"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp
new file mode 100644
index 000000000000..49113a3d0437
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp
@@ -0,0 +1,397 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <type_traits>
+
+// Test the feature test macros defined by <type_traits>
+
+/* Constant Value
+ __cpp_lib_bool_constant 201505L [C++17]
+ __cpp_lib_has_unique_object_representations 201606L [C++17]
+ __cpp_lib_integral_constant_callable 201304L [C++14]
+ __cpp_lib_is_aggregate 201703L [C++17]
+ __cpp_lib_is_constant_evaluated 201811L [C++2a]
+ __cpp_lib_is_final 201402L [C++14]
+ __cpp_lib_is_invocable 201703L [C++17]
+ __cpp_lib_is_null_pointer 201309L [C++14]
+ __cpp_lib_is_swappable 201603L [C++17]
+ __cpp_lib_logical_traits 201510L [C++17]
+ __cpp_lib_result_of_sfinae 201210L [C++14]
+ __cpp_lib_transformation_trait_aliases 201304L [C++14]
+ __cpp_lib_type_trait_variable_templates 201510L [C++17]
+ __cpp_lib_void_t 201411L [C++17]
+*/
+
+#include <type_traits>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_is_final
+# error "__cpp_lib_is_final should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_void_t
+# error "__cpp_lib_void_t should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++14"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++14"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++14"
+# endif
+
+# ifdef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++14"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14"
+# endif
+
+# ifdef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++14"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14"
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++14"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_void_t
+# error "__cpp_lib_void_t should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should be defined in c++17"
+# endif
+# if __cpp_lib_bool_constant != 201505L
+# error "__cpp_lib_bool_constant should have the value 201505L in c++17"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should be defined in c++17"
+# endif
+# if __cpp_lib_has_unique_object_representations != 201606L
+# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++17"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001
+# ifndef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should be defined in c++17"
+# endif
+# if __cpp_lib_is_aggregate != 201703L
+# error "__cpp_lib_is_aggregate should have the value 201703L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001 is not defined!"
+# endif
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++17"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should be defined in c++17"
+# endif
+# if __cpp_lib_is_invocable != 201703L
+# error "__cpp_lib_is_invocable should have the value 201703L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++17"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should be defined in c++17"
+# endif
+# if __cpp_lib_is_swappable != 201603L
+# error "__cpp_lib_is_swappable should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should be defined in c++17"
+# endif
+# if __cpp_lib_logical_traits != 201510L
+# error "__cpp_lib_logical_traits should have the value 201510L in c++17"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++17"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17"
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++17"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should be defined in c++17"
+# endif
+# if __cpp_lib_type_trait_variable_templates != 201510L
+# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17"
+# endif
+
+# ifndef __cpp_lib_void_t
+# error "__cpp_lib_void_t should be defined in c++17"
+# endif
+# if __cpp_lib_void_t != 201411L
+# error "__cpp_lib_void_t should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should be defined in c++2a"
+# endif
+# if __cpp_lib_bool_constant != 201505L
+# error "__cpp_lib_bool_constant should have the value 201505L in c++2a"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should be defined in c++2a"
+# endif
+# if __cpp_lib_has_unique_object_representations != 201606L
+# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++2a"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++2a"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001
+# ifndef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should be defined in c++2a"
+# endif
+# if __cpp_lib_is_aggregate != 201703L
+# error "__cpp_lib_is_aggregate should have the value 201703L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001 is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
+# endif
+# if __cpp_lib_is_constant_evaluated != 201811L
+# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++2a"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should be defined in c++2a"
+# endif
+# if __cpp_lib_is_invocable != 201703L
+# error "__cpp_lib_is_invocable should have the value 201703L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++2a"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should be defined in c++2a"
+# endif
+# if __cpp_lib_is_swappable != 201603L
+# error "__cpp_lib_is_swappable should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should be defined in c++2a"
+# endif
+# if __cpp_lib_logical_traits != 201510L
+# error "__cpp_lib_logical_traits should have the value 201510L in c++2a"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++2a"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++2a"
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++2a"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should be defined in c++2a"
+# endif
+# if __cpp_lib_type_trait_variable_templates != 201510L
+# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++2a"
+# endif
+
+# ifndef __cpp_lib_void_t
+# error "__cpp_lib_void_t should be defined in c++2a"
+# endif
+# if __cpp_lib_void_t != 201411L
+# error "__cpp_lib_void_t should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp
new file mode 100644
index 000000000000..9aa06e4db083
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <unordered_map>
+
+// Test the feature test macros defined by <unordered_map>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_generic_unordered_lookup 201811L [C++2a]
+ __cpp_lib_node_extract 201606L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+ __cpp_lib_unordered_map_try_emplace 201411L [C++17]
+*/
+
+#include <unordered_map>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++17"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17"
+# endif
+# if __cpp_lib_unordered_map_try_emplace != 201411L
+# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_unordered_lookup != 201811L
+# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++2a"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should be defined in c++2a"
+# endif
+# if __cpp_lib_unordered_map_try_emplace != 201411L
+# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp
new file mode 100644
index 000000000000..3153afd254cc
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <unordered_set>
+
+// Test the feature test macros defined by <unordered_set>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_generic_unordered_lookup 201811L [C++2a]
+ __cpp_lib_node_extract 201606L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <unordered_set>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++17"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_unordered_lookup != 201811L
+# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++2a"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp
new file mode 100644
index 000000000000..94bdb824a5d3
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp
@@ -0,0 +1,195 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <utility>
+
+// Test the feature test macros defined by <utility>
+
+/* Constant Value
+ __cpp_lib_as_const 201510L [C++17]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_exchange_function 201304L [C++14]
+ __cpp_lib_integer_sequence 201304L [C++14]
+ __cpp_lib_to_chars 201611L [C++17]
+ __cpp_lib_tuples_by_type 201304L [C++14]
+*/
+
+#include <utility>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_as_const
+# error "__cpp_lib_as_const should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should not be defined before c++14"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_as_const
+# error "__cpp_lib_as_const should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++14"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++14"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++14"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++14"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_as_const
+# error "__cpp_lib_as_const should be defined in c++17"
+# endif
+# if __cpp_lib_as_const != 201510L
+# error "__cpp_lib_as_const should have the value 201510L in c++17"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++17"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++17"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++17"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++17"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_as_const
+# error "__cpp_lib_as_const should be defined in c++2a"
+# endif
+# if __cpp_lib_as_const != 201510L
+# error "__cpp_lib_as_const should have the value 201510L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++2a"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++2a"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++2a"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++2a"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp
new file mode 100644
index 000000000000..d4ef3d7e0fcf
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <variant>
+
+// Test the feature test macros defined by <variant>
+
+/* Constant Value
+ __cpp_lib_variant 201606L [C++17]
+*/
+
+#include <variant>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++17"
+# endif
+# if __cpp_lib_variant != 201606L
+# error "__cpp_lib_variant should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++2a"
+# endif
+# if __cpp_lib_variant != 201606L
+# error "__cpp_lib_variant should have the value 201606L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp
new file mode 100644
index 000000000000..5cdeca06b5d0
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <vector>
+
+// Test the feature test macros defined by <vector>
+
+/* Constant Value
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_incomplete_container_elements 201505L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+*/
+
+#include <vector>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++17"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++2a"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
new file mode 100644
index 000000000000..5fa996967c0f
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
@@ -0,0 +1,2178 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <version>
+
+// Test the feature test macros defined by <version>
+
+/* Constant Value
+ __cpp_lib_addressof_constexpr 201603L [C++17]
+ __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
+ __cpp_lib_any 201606L [C++17]
+ __cpp_lib_apply 201603L [C++17]
+ __cpp_lib_array_constexpr 201603L [C++17]
+ __cpp_lib_as_const 201510L [C++17]
+ __cpp_lib_atomic_is_always_lock_free 201603L [C++17]
+ __cpp_lib_atomic_ref 201806L [C++2a]
+ __cpp_lib_bind_front 201811L [C++2a]
+ __cpp_lib_bit_cast 201806L [C++2a]
+ __cpp_lib_bool_constant 201505L [C++17]
+ __cpp_lib_boyer_moore_searcher 201603L [C++17]
+ __cpp_lib_byte 201603L [C++17]
+ __cpp_lib_char8_t 201811L [C++2a]
+ __cpp_lib_chrono 201611L [C++17]
+ __cpp_lib_chrono_udls 201304L [C++14]
+ __cpp_lib_clamp 201603L [C++17]
+ __cpp_lib_complex_udls 201309L [C++14]
+ __cpp_lib_concepts 201806L [C++2a]
+ __cpp_lib_constexpr_misc 201811L [C++2a]
+ __cpp_lib_constexpr_swap_algorithms 201806L [C++2a]
+ __cpp_lib_destroying_delete 201806L [C++2a]
+ __cpp_lib_enable_shared_from_this 201603L [C++17]
+ __cpp_lib_erase_if 201811L [C++2a]
+ __cpp_lib_exchange_function 201304L [C++14]
+ __cpp_lib_execution 201603L [C++17]
+ __cpp_lib_filesystem 201703L [C++17]
+ __cpp_lib_gcd_lcm 201606L [C++17]
+ __cpp_lib_generic_associative_lookup 201304L [C++14]
+ __cpp_lib_generic_unordered_lookup 201811L [C++2a]
+ __cpp_lib_hardware_interference_size 201703L [C++17]
+ __cpp_lib_has_unique_object_representations 201606L [C++17]
+ __cpp_lib_hypot 201603L [C++17]
+ __cpp_lib_incomplete_container_elements 201505L [C++17]
+ __cpp_lib_integer_sequence 201304L [C++14]
+ __cpp_lib_integral_constant_callable 201304L [C++14]
+ __cpp_lib_invoke 201411L [C++17]
+ __cpp_lib_is_aggregate 201703L [C++17]
+ __cpp_lib_is_constant_evaluated 201811L [C++2a]
+ __cpp_lib_is_final 201402L [C++14]
+ __cpp_lib_is_invocable 201703L [C++17]
+ __cpp_lib_is_null_pointer 201309L [C++14]
+ __cpp_lib_is_swappable 201603L [C++17]
+ __cpp_lib_launder 201606L [C++17]
+ __cpp_lib_list_remove_return_type 201806L [C++2a]
+ __cpp_lib_logical_traits 201510L [C++17]
+ __cpp_lib_make_from_tuple 201606L [C++17]
+ __cpp_lib_make_reverse_iterator 201402L [C++14]
+ __cpp_lib_make_unique 201304L [C++14]
+ __cpp_lib_map_try_emplace 201411L [C++17]
+ __cpp_lib_math_special_functions 201603L [C++17]
+ __cpp_lib_memory_resource 201603L [C++17]
+ __cpp_lib_node_extract 201606L [C++17]
+ __cpp_lib_nonmember_container_access 201411L [C++17]
+ __cpp_lib_not_fn 201603L [C++17]
+ __cpp_lib_null_iterators 201304L [C++14]
+ __cpp_lib_optional 201606L [C++17]
+ __cpp_lib_parallel_algorithm 201603L [C++17]
+ __cpp_lib_quoted_string_io 201304L [C++14]
+ __cpp_lib_ranges 201811L [C++2a]
+ __cpp_lib_raw_memory_algorithms 201606L [C++17]
+ __cpp_lib_result_of_sfinae 201210L [C++14]
+ __cpp_lib_robust_nonmodifying_seq_ops 201304L [C++14]
+ __cpp_lib_sample 201603L [C++17]
+ __cpp_lib_scoped_lock 201703L [C++17]
+ __cpp_lib_shared_mutex 201505L [C++17]
+ __cpp_lib_shared_ptr_arrays 201611L [C++17]
+ __cpp_lib_shared_ptr_weak_type 201606L [C++17]
+ __cpp_lib_shared_timed_mutex 201402L [C++14]
+ __cpp_lib_string_udls 201304L [C++14]
+ __cpp_lib_string_view 201606L [C++17]
+ __cpp_lib_three_way_comparison 201711L [C++2a]
+ __cpp_lib_to_chars 201611L [C++17]
+ __cpp_lib_transformation_trait_aliases 201304L [C++14]
+ __cpp_lib_transparent_operators 201210L [C++14]
+ 201510L [C++17]
+ __cpp_lib_tuple_element_t 201402L [C++14]
+ __cpp_lib_tuples_by_type 201304L [C++14]
+ __cpp_lib_type_trait_variable_templates 201510L [C++17]
+ __cpp_lib_uncaught_exceptions 201411L [C++17]
+ __cpp_lib_unordered_map_try_emplace 201411L [C++17]
+ __cpp_lib_variant 201606L [C++17]
+ __cpp_lib_void_t 201411L [C++17]
+*/
+
+#include <version>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_any
+# error "__cpp_lib_any should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_apply
+# error "__cpp_lib_apply should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_as_const
+# error "__cpp_lib_as_const should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_byte
+# error "__cpp_lib_byte should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_chrono
+# error "__cpp_lib_chrono should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_clamp
+# error "__cpp_lib_clamp should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_concepts
+# error "__cpp_lib_concepts should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_execution
+# error "__cpp_lib_execution should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_hypot
+# error "__cpp_lib_hypot should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_invoke
+# error "__cpp_lib_invoke should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_is_final
+# error "__cpp_lib_is_final should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_launder
+# error "__cpp_lib_launder should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_optional
+# error "__cpp_lib_optional should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_sample
+# error "__cpp_lib_sample should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should not be defined before c++14"
+# endif
+
+# ifdef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_void_t
+# error "__cpp_lib_void_t should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_any
+# error "__cpp_lib_any should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_apply
+# error "__cpp_lib_apply should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_as_const
+# error "__cpp_lib_as_const should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_byte
+# error "__cpp_lib_byte should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_chrono
+# error "__cpp_lib_chrono should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++14"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_clamp
+# error "__cpp_lib_clamp should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++14"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++14"
+# endif
+
+# ifdef __cpp_lib_concepts
+# error "__cpp_lib_concepts should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++14"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_execution
+# error "__cpp_lib_execution should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++14"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_hypot
+# error "__cpp_lib_hypot should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++14"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++14"
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++14"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_invoke
+# error "__cpp_lib_invoke should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++14"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++14"
+# endif
+
+# ifdef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++14"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14"
+# endif
+
+# ifdef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_launder
+# error "__cpp_lib_launder should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++14"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++14"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++14"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_optional
+# error "__cpp_lib_optional should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++14"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++14"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14"
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_sample
+# error "__cpp_lib_sample should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++14"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++14"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_string_view
+# error "__cpp_lib_string_view should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined before c++17"
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++14"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++14"
+# endif
+# if __cpp_lib_transparent_operators != 201210L
+# error "__cpp_lib_transparent_operators should have the value 201210L in c++14"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++14"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++14"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14"
+# endif
+
+# ifdef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_void_t
+# error "__cpp_lib_void_t should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# if TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should be defined in c++17"
+# endif
+# if __cpp_lib_addressof_constexpr != 201603L
+# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++17"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_apply
+# error "__cpp_lib_apply should be defined in c++17"
+# endif
+# if __cpp_lib_apply != 201603L
+# error "__cpp_lib_apply should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++17"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_as_const
+# error "__cpp_lib_as_const should be defined in c++17"
+# endif
+# if __cpp_lib_as_const != 201510L
+# error "__cpp_lib_as_const should have the value 201510L in c++17"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17"
+# endif
+# if __cpp_lib_atomic_is_always_lock_free != 201603L
+# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should be defined in c++17"
+# endif
+# if __cpp_lib_bool_constant != 201505L
+# error "__cpp_lib_bool_constant should have the value 201505L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should be defined in c++17"
+# endif
+# if __cpp_lib_boyer_moore_searcher != 201603L
+# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_byte
+# error "__cpp_lib_byte should be defined in c++17"
+# endif
+# if __cpp_lib_byte != 201603L
+# error "__cpp_lib_byte should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_chrono
+# error "__cpp_lib_chrono should be defined in c++17"
+# endif
+# if __cpp_lib_chrono != 201611L
+# error "__cpp_lib_chrono should have the value 201611L in c++17"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++17"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++17"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++17"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++17"
+# endif
+
+# ifdef __cpp_lib_concepts
+# error "__cpp_lib_concepts should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
+# endif
+
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should be defined in c++17"
+# endif
+# if __cpp_lib_enable_shared_from_this != 201603L
+# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17"
+# endif
+
+# ifdef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++17"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_execution
+# error "__cpp_lib_execution should be defined in c++17"
+# endif
+# if __cpp_lib_execution != 201603L
+# error "__cpp_lib_execution should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_execution
+# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should be defined in c++17"
+# endif
+# if __cpp_lib_filesystem != 201703L
+# error "__cpp_lib_filesystem should have the value 201703L in c++17"
+# endif
+
+# ifndef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should be defined in c++17"
+# endif
+# if __cpp_lib_gcd_lcm != 201606L
+# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++17"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17"
+# endif
+
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should be defined in c++17"
+# endif
+# if __cpp_lib_hardware_interference_size != 201703L
+# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should be defined in c++17"
+# endif
+# if __cpp_lib_has_unique_object_representations != 201606L
+# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_hypot
+# error "__cpp_lib_hypot should be defined in c++17"
+# endif
+# if __cpp_lib_hypot != 201603L
+# error "__cpp_lib_hypot should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++17"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++17"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++17"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_invoke
+# error "__cpp_lib_invoke should be defined in c++17"
+# endif
+# if __cpp_lib_invoke != 201411L
+# error "__cpp_lib_invoke should have the value 201411L in c++17"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001
+# ifndef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should be defined in c++17"
+# endif
+# if __cpp_lib_is_aggregate != 201703L
+# error "__cpp_lib_is_aggregate should have the value 201703L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001 is not defined!"
+# endif
+# endif
+
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++17"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should be defined in c++17"
+# endif
+# if __cpp_lib_is_invocable != 201703L
+# error "__cpp_lib_is_invocable should have the value 201703L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++17"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17"
+# endif
+
+# ifndef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should be defined in c++17"
+# endif
+# if __cpp_lib_is_swappable != 201603L
+# error "__cpp_lib_is_swappable should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_launder
+# error "__cpp_lib_launder should be defined in c++17"
+# endif
+# if __cpp_lib_launder != 201606L
+# error "__cpp_lib_launder should have the value 201606L in c++17"
+# endif
+
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should be defined in c++17"
+# endif
+# if __cpp_lib_logical_traits != 201510L
+# error "__cpp_lib_logical_traits should have the value 201510L in c++17"
+# endif
+
+# ifndef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should be defined in c++17"
+# endif
+# if __cpp_lib_make_from_tuple != 201606L
+# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++17"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++17"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should be defined in c++17"
+# endif
+# if __cpp_lib_map_try_emplace != 201411L
+# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should be defined in c++17"
+# endif
+# if __cpp_lib_math_special_functions != 201603L
+# error "__cpp_lib_math_special_functions should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should be defined in c++17"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+# error "__cpp_lib_memory_resource should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++17"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++17"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should be defined in c++17"
+# endif
+# if __cpp_lib_not_fn != 201603L
+# error "__cpp_lib_not_fn should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++17"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_optional
+# error "__cpp_lib_optional should be defined in c++17"
+# endif
+# if __cpp_lib_optional != 201606L
+# error "__cpp_lib_optional should have the value 201606L in c++17"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++17"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++17"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17"
+# endif
+
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined before c++2a"
+# endif
+
+# ifndef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should be defined in c++17"
+# endif
+# if __cpp_lib_raw_memory_algorithms != 201606L
+# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++17"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17"
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_sample
+# error "__cpp_lib_sample should be defined in c++17"
+# endif
+# if __cpp_lib_sample != 201603L
+# error "__cpp_lib_sample should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should be defined in c++17"
+# endif
+# if __cpp_lib_scoped_lock != 201703L
+# error "__cpp_lib_scoped_lock should have the value 201703L in c++17"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should be defined in c++17"
+# endif
+# if __cpp_lib_shared_mutex != 201505L
+# error "__cpp_lib_shared_mutex should have the value 201505L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should be defined in c++17"
+# endif
+# if __cpp_lib_shared_ptr_arrays != 201611L
+# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17"
+# endif
+# if __cpp_lib_shared_ptr_weak_type != 201606L
+# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++17"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++17"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++17"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++17"
+# endif
+
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined before c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++17"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++17"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++17"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++17"
+# endif
+# if __cpp_lib_transparent_operators != 201510L
+# error "__cpp_lib_transparent_operators should have the value 201510L in c++17"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++17"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++17"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17"
+# endif
+
+# ifndef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should be defined in c++17"
+# endif
+# if __cpp_lib_type_trait_variable_templates != 201510L
+# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17"
+# endif
+
+# ifndef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should be defined in c++17"
+# endif
+# if __cpp_lib_uncaught_exceptions != 201411L
+# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17"
+# endif
+# if __cpp_lib_unordered_map_try_emplace != 201411L
+# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17"
+# endif
+
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++17"
+# endif
+# if __cpp_lib_variant != 201606L
+# error "__cpp_lib_variant should have the value 201606L in c++17"
+# endif
+
+# ifndef __cpp_lib_void_t
+# error "__cpp_lib_void_t should be defined in c++17"
+# endif
+# if __cpp_lib_void_t != 201411L
+# error "__cpp_lib_void_t should have the value 201411L in c++17"
+# endif
+
+#elif TEST_STD_VER > 17
+
+# if TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should be defined in c++2a"
+# endif
+# if __cpp_lib_addressof_constexpr != 201603L
+# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_addressof_constexpr
+# error "__cpp_lib_addressof_constexpr should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_allocator_traits_is_always_equal
+# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++2a"
+# endif
+# if __cpp_lib_allocator_traits_is_always_equal != 201411L
+# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++2a"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_apply
+# error "__cpp_lib_apply should be defined in c++2a"
+# endif
+# if __cpp_lib_apply != 201603L
+# error "__cpp_lib_apply should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_array_constexpr
+# error "__cpp_lib_array_constexpr should be defined in c++2a"
+# endif
+# if __cpp_lib_array_constexpr != 201603L
+# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_as_const
+# error "__cpp_lib_as_const should be defined in c++2a"
+# endif
+# if __cpp_lib_as_const != 201510L
+# error "__cpp_lib_as_const should have the value 201510L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++2a"
+# endif
+# if __cpp_lib_atomic_is_always_lock_free != 201603L
+# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_atomic_is_always_lock_free
+# error "__cpp_lib_atomic_is_always_lock_free should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should be defined in c++2a"
+# endif
+# if __cpp_lib_atomic_ref != 201806L
+# error "__cpp_lib_atomic_ref should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_atomic_ref
+# error "__cpp_lib_atomic_ref should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should be defined in c++2a"
+# endif
+# if __cpp_lib_bind_front != 201811L
+# error "__cpp_lib_bind_front should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_bind_front
+# error "__cpp_lib_bind_front should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should be defined in c++2a"
+# endif
+# if __cpp_lib_bit_cast != 201806L
+# error "__cpp_lib_bit_cast should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_bit_cast
+# error "__cpp_lib_bit_cast should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_bool_constant
+# error "__cpp_lib_bool_constant should be defined in c++2a"
+# endif
+# if __cpp_lib_bool_constant != 201505L
+# error "__cpp_lib_bool_constant should have the value 201505L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should be defined in c++2a"
+# endif
+# if __cpp_lib_boyer_moore_searcher != 201603L
+# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_boyer_moore_searcher
+# error "__cpp_lib_boyer_moore_searcher should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_byte
+# error "__cpp_lib_byte should be defined in c++2a"
+# endif
+# if __cpp_lib_byte != 201603L
+# error "__cpp_lib_byte should have the value 201603L in c++2a"
+# endif
+
+# if defined(__cpp_char8_t)
+# ifndef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should be defined in c++2a"
+# endif
+# if __cpp_lib_char8_t != 201811L
+# error "__cpp_lib_char8_t should have the value 201811L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_char8_t
+# error "__cpp_lib_char8_t should not be defined when defined(__cpp_char8_t) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_chrono
+# error "__cpp_lib_chrono should be defined in c++2a"
+# endif
+# if __cpp_lib_chrono != 201611L
+# error "__cpp_lib_chrono should have the value 201611L in c++2a"
+# endif
+
+# ifndef __cpp_lib_chrono_udls
+# error "__cpp_lib_chrono_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_chrono_udls != 201304L
+# error "__cpp_lib_chrono_udls should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++2a"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_complex_udls
+# error "__cpp_lib_complex_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_complex_udls != 201309L
+# error "__cpp_lib_complex_udls should have the value 201309L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_concepts
+# error "__cpp_lib_concepts should be defined in c++2a"
+# endif
+# if __cpp_lib_concepts != 201806L
+# error "__cpp_lib_concepts should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_concepts
+# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_misc != 201811L
+# error "__cpp_lib_constexpr_misc should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_misc
+# error "__cpp_lib_constexpr_misc should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should be defined in c++2a"
+# endif
+# if __cpp_lib_constexpr_swap_algorithms != 201806L
+# error "__cpp_lib_constexpr_swap_algorithms should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_constexpr_swap_algorithms
+# error "__cpp_lib_constexpr_swap_algorithms should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should be defined in c++2a"
+# endif
+# if __cpp_lib_destroying_delete != 201806L
+# error "__cpp_lib_destroying_delete should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_destroying_delete
+# error "__cpp_lib_destroying_delete should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_enable_shared_from_this
+# error "__cpp_lib_enable_shared_from_this should be defined in c++2a"
+# endif
+# if __cpp_lib_enable_shared_from_this != 201603L
+# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_erase_if
+# error "__cpp_lib_erase_if should be defined in c++2a"
+# endif
+# if __cpp_lib_erase_if != 201811L
+# error "__cpp_lib_erase_if should have the value 201811L in c++2a"
+# endif
+
+# ifndef __cpp_lib_exchange_function
+# error "__cpp_lib_exchange_function should be defined in c++2a"
+# endif
+# if __cpp_lib_exchange_function != 201304L
+# error "__cpp_lib_exchange_function should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_execution
+# error "__cpp_lib_execution should be defined in c++2a"
+# endif
+# if __cpp_lib_execution != 201603L
+# error "__cpp_lib_execution should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_execution
+# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_filesystem
+# error "__cpp_lib_filesystem should be defined in c++2a"
+# endif
+# if __cpp_lib_filesystem != 201703L
+# error "__cpp_lib_filesystem should have the value 201703L in c++2a"
+# endif
+
+# ifndef __cpp_lib_gcd_lcm
+# error "__cpp_lib_gcd_lcm should be defined in c++2a"
+# endif
+# if __cpp_lib_gcd_lcm != 201606L
+# error "__cpp_lib_gcd_lcm should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_generic_associative_lookup
+# error "__cpp_lib_generic_associative_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_associative_lookup != 201304L
+# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should be defined in c++2a"
+# endif
+# if __cpp_lib_generic_unordered_lookup != 201811L
+# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_generic_unordered_lookup
+# error "__cpp_lib_generic_unordered_lookup should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_hardware_interference_size
+# error "__cpp_lib_hardware_interference_size should be defined in c++2a"
+# endif
+# if __cpp_lib_hardware_interference_size != 201703L
+# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++2a"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700
+# ifndef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should be defined in c++2a"
+# endif
+# if __cpp_lib_has_unique_object_representations != 201606L
+# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_has_unique_object_representations
+# error "__cpp_lib_has_unique_object_representations should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700 is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_hypot
+# error "__cpp_lib_hypot should be defined in c++2a"
+# endif
+# if __cpp_lib_hypot != 201603L
+# error "__cpp_lib_hypot should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_incomplete_container_elements
+# error "__cpp_lib_incomplete_container_elements should be defined in c++2a"
+# endif
+# if __cpp_lib_incomplete_container_elements != 201505L
+# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++2a"
+# endif
+
+# ifndef __cpp_lib_integer_sequence
+# error "__cpp_lib_integer_sequence should be defined in c++2a"
+# endif
+# if __cpp_lib_integer_sequence != 201304L
+# error "__cpp_lib_integer_sequence should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_integral_constant_callable
+# error "__cpp_lib_integral_constant_callable should be defined in c++2a"
+# endif
+# if __cpp_lib_integral_constant_callable != 201304L
+# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_invoke
+# error "__cpp_lib_invoke should be defined in c++2a"
+# endif
+# if __cpp_lib_invoke != 201411L
+# error "__cpp_lib_invoke should have the value 201411L in c++2a"
+# endif
+
+# if TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001
+# ifndef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should be defined in c++2a"
+# endif
+# if __cpp_lib_is_aggregate != 201703L
+# error "__cpp_lib_is_aggregate should have the value 201703L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_is_aggregate
+# error "__cpp_lib_is_aggregate should not be defined when TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001 is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
+# endif
+# if __cpp_lib_is_constant_evaluated != 201811L
+# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_is_constant_evaluated
+# error "__cpp_lib_is_constant_evaluated should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_is_final
+# error "__cpp_lib_is_final should be defined in c++2a"
+# endif
+# if __cpp_lib_is_final != 201402L
+# error "__cpp_lib_is_final should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_invocable
+# error "__cpp_lib_is_invocable should be defined in c++2a"
+# endif
+# if __cpp_lib_is_invocable != 201703L
+# error "__cpp_lib_is_invocable should have the value 201703L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_null_pointer
+# error "__cpp_lib_is_null_pointer should be defined in c++2a"
+# endif
+# if __cpp_lib_is_null_pointer != 201309L
+# error "__cpp_lib_is_null_pointer should have the value 201309L in c++2a"
+# endif
+
+# ifndef __cpp_lib_is_swappable
+# error "__cpp_lib_is_swappable should be defined in c++2a"
+# endif
+# if __cpp_lib_is_swappable != 201603L
+# error "__cpp_lib_is_swappable should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_launder
+# error "__cpp_lib_launder should be defined in c++2a"
+# endif
+# if __cpp_lib_launder != 201606L
+# error "__cpp_lib_launder should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should be defined in c++2a"
+# endif
+# if __cpp_lib_list_remove_return_type != 201806L
+# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_list_remove_return_type
+# error "__cpp_lib_list_remove_return_type should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_logical_traits
+# error "__cpp_lib_logical_traits should be defined in c++2a"
+# endif
+# if __cpp_lib_logical_traits != 201510L
+# error "__cpp_lib_logical_traits should have the value 201510L in c++2a"
+# endif
+
+# ifndef __cpp_lib_make_from_tuple
+# error "__cpp_lib_make_from_tuple should be defined in c++2a"
+# endif
+# if __cpp_lib_make_from_tuple != 201606L
+# error "__cpp_lib_make_from_tuple should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_make_reverse_iterator
+# error "__cpp_lib_make_reverse_iterator should be defined in c++2a"
+# endif
+# if __cpp_lib_make_reverse_iterator != 201402L
+# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_make_unique
+# error "__cpp_lib_make_unique should be defined in c++2a"
+# endif
+# if __cpp_lib_make_unique != 201304L
+# error "__cpp_lib_make_unique should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_map_try_emplace
+# error "__cpp_lib_map_try_emplace should be defined in c++2a"
+# endif
+# if __cpp_lib_map_try_emplace != 201411L
+# error "__cpp_lib_map_try_emplace should have the value 201411L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should be defined in c++2a"
+# endif
+# if __cpp_lib_math_special_functions != 201603L
+# error "__cpp_lib_math_special_functions should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_math_special_functions
+# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should be defined in c++2a"
+# endif
+# if __cpp_lib_memory_resource != 201603L
+# error "__cpp_lib_memory_resource should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_memory_resource
+# error "__cpp_lib_memory_resource should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_node_extract
+# error "__cpp_lib_node_extract should be defined in c++2a"
+# endif
+# if __cpp_lib_node_extract != 201606L
+# error "__cpp_lib_node_extract should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_nonmember_container_access
+# error "__cpp_lib_nonmember_container_access should be defined in c++2a"
+# endif
+# if __cpp_lib_nonmember_container_access != 201411L
+# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_not_fn
+# error "__cpp_lib_not_fn should be defined in c++2a"
+# endif
+# if __cpp_lib_not_fn != 201603L
+# error "__cpp_lib_not_fn should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_null_iterators
+# error "__cpp_lib_null_iterators should be defined in c++2a"
+# endif
+# if __cpp_lib_null_iterators != 201304L
+# error "__cpp_lib_null_iterators should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_optional
+# error "__cpp_lib_optional should be defined in c++2a"
+# endif
+# if __cpp_lib_optional != 201606L
+# error "__cpp_lib_optional should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++2a"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_quoted_string_io
+# error "__cpp_lib_quoted_string_io should be defined in c++2a"
+# endif
+# if __cpp_lib_quoted_string_io != 201304L
+# error "__cpp_lib_quoted_string_io should have the value 201304L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_ranges
+# error "__cpp_lib_ranges should be defined in c++2a"
+# endif
+# if __cpp_lib_ranges != 201811L
+# error "__cpp_lib_ranges should have the value 201811L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_ranges
+# error "__cpp_lib_ranges should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_raw_memory_algorithms
+# error "__cpp_lib_raw_memory_algorithms should be defined in c++2a"
+# endif
+# if __cpp_lib_raw_memory_algorithms != 201606L
+# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_result_of_sfinae
+# error "__cpp_lib_result_of_sfinae should be defined in c++2a"
+# endif
+# if __cpp_lib_result_of_sfinae != 201210L
+# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++2a"
+# endif
+
+# ifndef __cpp_lib_robust_nonmodifying_seq_ops
+# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++2a"
+# endif
+# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L
+# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_sample
+# error "__cpp_lib_sample should be defined in c++2a"
+# endif
+# if __cpp_lib_sample != 201603L
+# error "__cpp_lib_sample should have the value 201603L in c++2a"
+# endif
+
+# ifndef __cpp_lib_scoped_lock
+# error "__cpp_lib_scoped_lock should be defined in c++2a"
+# endif
+# if __cpp_lib_scoped_lock != 201703L
+# error "__cpp_lib_scoped_lock should have the value 201703L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_mutex != 201505L
+# error "__cpp_lib_shared_mutex should have the value 201505L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_shared_mutex
+# error "__cpp_lib_shared_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_ptr_arrays != 201611L
+# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_shared_ptr_arrays
+# error "__cpp_lib_shared_ptr_arrays should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_shared_ptr_weak_type
+# error "__cpp_lib_shared_ptr_weak_type should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_ptr_weak_type != 201606L
+# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_HAS_NO_THREADS)
+# ifndef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should be defined in c++2a"
+# endif
+# if __cpp_lib_shared_timed_mutex != 201402L
+# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++2a"
+# endif
+# else
+# ifdef __cpp_lib_shared_timed_mutex
+# error "__cpp_lib_shared_timed_mutex should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
+# endif
+# endif
+
+# ifndef __cpp_lib_string_udls
+# error "__cpp_lib_string_udls should be defined in c++2a"
+# endif
+# if __cpp_lib_string_udls != 201304L
+# error "__cpp_lib_string_udls should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_string_view
+# error "__cpp_lib_string_view should be defined in c++2a"
+# endif
+# if __cpp_lib_string_view != 201606L
+# error "__cpp_lib_string_view should have the value 201606L in c++2a"
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should be defined in c++2a"
+# endif
+# if __cpp_lib_three_way_comparison != 201711L
+# error "__cpp_lib_three_way_comparison should have the value 201711L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_three_way_comparison
+# error "__cpp_lib_three_way_comparison should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++2a"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++2a"
+# endif
+# else // _LIBCPP_VERSION
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+# ifndef __cpp_lib_transformation_trait_aliases
+# error "__cpp_lib_transformation_trait_aliases should be defined in c++2a"
+# endif
+# if __cpp_lib_transformation_trait_aliases != 201304L
+# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_transparent_operators
+# error "__cpp_lib_transparent_operators should be defined in c++2a"
+# endif
+# if __cpp_lib_transparent_operators != 201510L
+# error "__cpp_lib_transparent_operators should have the value 201510L in c++2a"
+# endif
+
+# ifndef __cpp_lib_tuple_element_t
+# error "__cpp_lib_tuple_element_t should be defined in c++2a"
+# endif
+# if __cpp_lib_tuple_element_t != 201402L
+# error "__cpp_lib_tuple_element_t should have the value 201402L in c++2a"
+# endif
+
+# ifndef __cpp_lib_tuples_by_type
+# error "__cpp_lib_tuples_by_type should be defined in c++2a"
+# endif
+# if __cpp_lib_tuples_by_type != 201304L
+# error "__cpp_lib_tuples_by_type should have the value 201304L in c++2a"
+# endif
+
+# ifndef __cpp_lib_type_trait_variable_templates
+# error "__cpp_lib_type_trait_variable_templates should be defined in c++2a"
+# endif
+# if __cpp_lib_type_trait_variable_templates != 201510L
+# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++2a"
+# endif
+
+# ifndef __cpp_lib_uncaught_exceptions
+# error "__cpp_lib_uncaught_exceptions should be defined in c++2a"
+# endif
+# if __cpp_lib_uncaught_exceptions != 201411L
+# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_unordered_map_try_emplace
+# error "__cpp_lib_unordered_map_try_emplace should be defined in c++2a"
+# endif
+# if __cpp_lib_unordered_map_try_emplace != 201411L
+# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++2a"
+# endif
+
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++2a"
+# endif
+# if __cpp_lib_variant != 201606L
+# error "__cpp_lib_variant should have the value 201606L in c++2a"
+# endif
+
+# ifndef __cpp_lib_void_t
+# error "__cpp_lib_void_t should be defined in c++2a"
+# endif
+# if __cpp_lib_void_t != 201411L
+# error "__cpp_lib_void_t should have the value 201411L in c++2a"
+# endif
+
+#endif // TEST_STD_VER > 17
+
+int main() {}
diff --git a/test/std/language.support/support.runtime/cstdlib.pass.cpp b/test/std/language.support/support.runtime/cstdlib.pass.cpp
index e9dda6cee4ee..02c8c9fd8bb3 100644
--- a/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -75,10 +75,8 @@ int main()
static_assert((std::is_same<decltype(std::srand(0)), void>::value), "");
// Microsoft does not implement aligned_alloc in their C library
-#ifndef TEST_COMPILER_C1XX
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
- static_assert((std::is_same<decltype(std::aligned_alloc(0,0)), void*>::value), "");
-#endif
+#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES) && !defined(_WIN32)
+ static_assert((std::is_same<decltype(aligned_alloc(0,0)), void*>::value), "");
#endif
static_assert((std::is_same<decltype(std::calloc(0,0)), void*>::value), "");
diff --git a/test/std/language.support/support.runtime/ctime.pass.cpp b/test/std/language.support/support.runtime/ctime.pass.cpp
index 908dc480884c..d80bc198293e 100644
--- a/test/std/language.support/support.runtime/ctime.pass.cpp
+++ b/test/std/language.support/support.runtime/ctime.pass.cpp
@@ -45,7 +45,7 @@ int main()
static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), "");
static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), "");
static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_TIMESPEC_GET)
static_assert((std::is_same<decltype(std::timespec_get(nullptr, 0)), int>::value), "");
#endif
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
diff --git a/test/std/language.support/support.start.term/quick_exit.pass.cpp b/test/std/language.support/support.start.term/quick_exit.pass.cpp
index bcfdbb75402e..2bf2ea790653 100644
--- a/test/std/language.support/support.start.term/quick_exit.pass.cpp
+++ b/test/std/language.support/support.start.term/quick_exit.pass.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
+// UNSUPPORTED: c++98, c++03
// test quick_exit and at_quick_exit
diff --git a/test/std/language.support/support.start.term/quick_exit_check1.fail.cpp b/test/std/language.support/support.start.term/quick_exit_check1.fail.cpp
index 8b9729379163..f42498e3d7b9 100644
--- a/test/std/language.support/support.start.term/quick_exit_check1.fail.cpp
+++ b/test/std/language.support/support.start.term/quick_exit_check1.fail.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
+// UNSUPPORTED: c++98, c++03
// test that referencing at_quick_exit when _LIBCPP_HAS_QUICK_EXIT is not defined
// results in a compile error.
diff --git a/test/std/language.support/support.start.term/quick_exit_check2.fail.cpp b/test/std/language.support/support.start.term/quick_exit_check2.fail.cpp
index 395914136820..c49704f99aea 100644
--- a/test/std/language.support/support.start.term/quick_exit_check2.fail.cpp
+++ b/test/std/language.support/support.start.term/quick_exit_check2.fail.cpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
+// UNSUPPORTED: c++98, c++03
// test that referencing quick_exit when _LIBCPP_HAS_QUICK_EXIT is not defined
// results in a compile error.
diff --git a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
index b39e9ad74dc4..4f738076e406 100644
--- a/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
+++ b/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// <locale>
diff --git a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
index d7bcb2908d72..e4cabf6efa05 100644
--- a/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
+++ b/test/std/localization/locale.categories/category.ctype/locale.codecvt/locale.codecvt.members/wchar_t_out.pass.cpp
@@ -20,6 +20,7 @@
#include <vector>
#include <cassert>
#include <cstddef>
+#include <cstring>
typedef std::codecvt<wchar_t, char, std::mbstate_t> F;
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
index bebc1f27bb34..ce046e61e028 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
index 7776c67a6be2..5b56ab3e7e08 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
@@ -9,6 +9,9 @@
//
// This test is passing in an uncontrolled manner in some Apple environment.
// UNSUPPORTED: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// Failure related to GLIBC's use of U00A0 as mon_thousands_sep
// and U002E as mon_decimal_point.
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
index 07a33f7663b6..4e62a1bc007c 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.zh_CN.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
index 2b431dc529d8..2ba29dfff601 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
index 4d805b0f7adf..56fb85058517 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
@@ -9,6 +9,9 @@
//
// This test is passing in an uncontrolled manner in some Apple environment.
// UNSUPPORTED: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// Failure related to GLIBC's use of U00A0 as mon_thousands_sep
// and U002E as mon_decimal_point.
diff --git a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
index 633e1885e711..1036969bb38a 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.zh_CN.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
index 3a9adc4bbc1e..c6cab19b2163 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
index b0b9da0b6949..f050164b6c0b 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
index 3fe9faf847f4..edbaf8600184 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
index 7038ab16e100..f401b72d860a 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
//
// XFAIL: apple-darwin
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
index ca8abf09b830..90fb7193e801 100644
--- a/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
+++ b/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_MONETARY at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
index d900c3764a1f..570b8306cee8 100644
--- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
+++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long.pass.cpp
@@ -17,6 +17,7 @@
#include <locale>
#include <ios>
#include <cassert>
+#include <limits>
#include <streambuf>
#include "test_iterators.h"
@@ -46,6 +47,7 @@ int main()
const my_facet f(1);
std::ios ios(0);
long v = -1;
+ const std::ios_base::fmtflags zf = static_cast<std::ios_base::fmtflags>(0);
{
const char str[] = "123";
assert((ios.flags() & ios.basefield) == ios.dec);
@@ -110,7 +112,7 @@ int main()
}
{
const char str[] = "123";
- ios.setf(0, ios.basefield);
+ ios.setf(zf, ios.basefield);
std::ios_base::iostate err = ios.goodbit;
input_iterator<const char*> iter =
f.get(input_iterator<const char*>(str),
@@ -122,7 +124,7 @@ int main()
}
{
const char str[] = "0x123";
- ios.setf(0, ios.basefield);
+ ios.setf(zf, ios.basefield);
std::ios_base::iostate err = ios.goodbit;
input_iterator<const char*> iter =
f.get(input_iterator<const char*>(str),
@@ -134,7 +136,7 @@ int main()
}
{
const char str[] = "0123";
- ios.setf(0, ios.basefield);
+ ios.setf(zf, ios.basefield);
std::ios_base::iostate err = ios.goodbit;
input_iterator<const char*> iter =
f.get(input_iterator<const char*>(str),
@@ -146,7 +148,7 @@ int main()
}
{
const char str[] = "2-";
- ios.setf(0, ios.basefield);
+ ios.setf(zf, ios.basefield);
std::ios_base::iostate err = ios.goodbit;
input_iterator<const char*> iter =
f.get(input_iterator<const char*>(str),
diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp
index e2218fffb396..ab02716e3470 100644
--- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp
+++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp
@@ -52,7 +52,7 @@ void check_limits()
}
}
-int main(void)
+int main()
{
check_limits<short>();
check_limits<unsigned short>();
diff --git a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp
index bd9b3f05de7a..bb40f31dbb14 100644
--- a/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp
+++ b/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_neg_one.pass.cpp
@@ -14,6 +14,7 @@
// iter_type get(iter_type in, iter_type end, ios_base&,
// ios_base::iostate& err, unsigned int& v) const;
+#include <limits>
#include <locale>
#include <ios>
#include <cassert>
@@ -148,7 +149,7 @@ void test_negate() {
}
}
-int main(void)
+int main()
{
test_neg_one<long>();
test_neg_one<long long>();
diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
index af15b174bcd2..2b6ade5c09e8 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_TIME at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp
index 1cd9f462e38e..ec1e3e7c951d 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_TIME at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
index 72b63278d71d..6cf3b6aef256 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_TIME at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
index 4a2b3819b507..1e7c170da7fb 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_TIME at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
index 3e7538d6625b..8e79357b5c16 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_TIME at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
index f3df52a21b89..1f2aeeabdb81 100644
--- a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
+++ b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_NUMERIC at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
index 0dedf78c9e81..b84f3a1c7edc 100644
--- a/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
+++ b/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_NUMERIC at the moment
+// XFAIL: netbsd
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
index aef2ea93d667..7ba64b05186d 100644
--- a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support most of LC_* at the moment
+// XFAIL: netbsd
// REQUIRES: locale.ru_RU.UTF-8
// REQUIRES: locale.zh_CN.UTF-8
diff --git a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
index e25fe389392d..6a79d3943d5e 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
@@ -11,8 +11,8 @@
// REQUIRES: locale.ru_RU.UTF-8
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: availability_markup=macosx10.8
-// XFAIL: availability_markup=macosx10.7
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
index 72d47a3914f3..5bf6befed9fc 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
@@ -11,8 +11,8 @@
// REQUIRES: locale.ru_RU.UTF-8
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: availability_markup=macosx10.8
-// XFAIL: availability_markup=macosx10.7
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
index 26ddfa600ea5..946e8b53030a 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
@@ -11,8 +11,8 @@
// REQUIRES: locale.ru_RU.UTF-8
// UNSUPPORTED: sanitizer-new-delete
-// XFAIL: availability_markup=macosx10.8
-// XFAIL: availability_markup=macosx10.7
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <locale>
diff --git a/test/std/numerics/c.math/cmath.pass.cpp b/test/std/numerics/c.math/cmath.pass.cpp
index cc535e374396..b02bdbe6447d 100644
--- a/test/std/numerics/c.math/cmath.pass.cpp
+++ b/test/std/numerics/c.math/cmath.pass.cpp
@@ -16,6 +16,7 @@
#include "test_macros.h"
#include "hexfloat.h"
+#include "truncate_fp.h"
// convertible to int/float/double/etc
template <class T, int N=0>
@@ -860,7 +861,7 @@ void test_cbrt()
static_assert((std::is_same<decltype(std::cbrtf(0)), float>::value), "");
static_assert((std::is_same<decltype(std::cbrtl(0)), long double>::value), "");
static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), "");
- assert(std::cbrt(1) == 1);
+ assert(truncate_fp(std::cbrt(1)) == 1);
}
void test_copysign()
diff --git a/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp b/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
index 4d866acb8f43..24644e307799 100644
--- a/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
+++ b/test/std/numerics/complex.number/complex.ops/stream_input.pass.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: with_system_cxx_lib=macosx10.7
-
// <complex>
// template<class T, class charT, class traits>
diff --git a/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq_all_zero.pass.cpp b/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq_all_zero.pass.cpp
new file mode 100644
index 000000000000..4599348f4a09
--- /dev/null
+++ b/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_sseq_all_zero.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+// template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+// UIntType a, size_t u, UIntType d, size_t s,
+// UIntType b, size_t t,
+// UIntType c, size_t l, UIntType f>
+// class mersenne_twister_engine;
+
+// template <class Sseq> explicit mersenne_twister_engine(Sseq &q);
+//
+// [ ... ] Finally, if the most significant $w-r$ bits of $X_{-n}$ are zero,
+// and if each of the other resulting $X_i$ is $0$, changes $X_{-n}$ to
+// $ 2^{w-1} $.
+
+#include <random>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#if TEST_STD_VER >= 11
+#include <initializer_list>
+#endif
+
+struct all_zero_seed_seq {
+ typedef unsigned int result_type;
+
+ all_zero_seed_seq() {}
+
+ template <typename InputIterator>
+ all_zero_seed_seq(InputIterator, InputIterator) {}
+#if TEST_STD_VER >= 11
+ all_zero_seed_seq(std::initializer_list<result_type>) {}
+#endif
+
+ template <typename RandomAccessIterator>
+ void generate(RandomAccessIterator rb, RandomAccessIterator re) {
+ std::fill(rb, re, 0u);
+ }
+
+ std::size_t size() const { return 0u; }
+ template <typename OutputIterator> void param(OutputIterator) const {}
+};
+
+template <typename result_type, std::size_t word_size>
+void test(void) {
+ const std::size_t state_size = 1u;
+ const std::size_t shift_size = 1u;
+ const std::size_t tempering_l = word_size;
+
+ all_zero_seed_seq q;
+ std::mersenne_twister_engine<result_type, word_size, state_size,
+ shift_size,
+ 0u,
+ 0x0,
+ 0u, 0x0, 0u, 0x0, 0u, 0x0,
+ tempering_l,
+ 0u>
+ e(q);
+
+ const result_type Xneg1 = result_type(1) << (word_size - 1);
+ const result_type Y = Xneg1;
+ const result_type X0 = Xneg1 ^ (Y >> 1);
+ assert(e() == X0);
+}
+
+int main() {
+ // Test for k == 1: word_size <= 32.
+ test<unsigned short, 3u>();
+
+ // Test for k == 2: (32 < word_size <= 64).
+ test<unsigned long long, 33u>();
+}
diff --git a/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp b/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp
index 7433e28e4935..df2acbe9e867 100644
--- a/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp
+++ b/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp
@@ -15,6 +15,8 @@
#include <random>
#include <cassert>
+#include "truncate_fp.h"
+
int main()
{
{
@@ -22,35 +24,35 @@ int main()
typedef float F;
E r;
F f = std::generate_canonical<F, 0>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef float F;
E r;
F f = std::generate_canonical<F, 1>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef float F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits - 1>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef float F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef float F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits + 1>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
@@ -58,43 +60,43 @@ int main()
typedef double F;
E r;
F f = std::generate_canonical<F, 0>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef double F;
E r;
F f = std::generate_canonical<F, 1>(r);
- assert(f == (16807 - E::min()) / (E::max() - E::min() + F(1)));
+ assert(f == truncate_fp((16807 - E::min()) / (E::max() - E::min() + F(1))));
}
{
typedef std::minstd_rand0 E;
typedef double F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits - 1>(r);
- assert(f ==
+ assert(f == truncate_fp(
(16807 - E::min() +
(282475249 - E::min()) * (E::max() - E::min() + F(1))) /
- ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))));
+ ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))));
}
{
typedef std::minstd_rand0 E;
typedef double F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits>(r);
- assert(f ==
+ assert(f == truncate_fp(
(16807 - E::min() +
(282475249 - E::min()) * (E::max() - E::min() + F(1))) /
- ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))));
+ ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))));
}
{
typedef std::minstd_rand0 E;
typedef double F;
E r;
F f = std::generate_canonical<F, std::numeric_limits<F>::digits + 1>(r);
- assert(f ==
+ assert(f == truncate_fp(
(16807 - E::min() +
(282475249 - E::min()) * (E::max() - E::min() + F(1))) /
- ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1))));
+ ((E::max() - E::min() + F(1)) * (E::max() - E::min() + F(1)))));
}
}
diff --git a/test/std/re/re.alg/re.alg.match/basic.pass.cpp b/test/std/re/re.alg/re.alg.match/basic.pass.cpp
index cb23cfa15d24..5140ec91762a 100644
--- a/test/std/re/re.alg/re.alg.match/basic.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/basic.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
index ae42b46668b0..a676e9e52bcc 100644
--- a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.match/extended.pass.cpp b/test/std/re/re.alg/re.alg.match/extended.pass.cpp
index aac03839a05d..8aa71f75d748 100644
--- a/test/std/re/re.alg/re.alg.match/extended.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/extended.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.match/inverted_character_classes.pass.cpp b/test/std/re/re.alg/re.alg.match/inverted_character_classes.pass.cpp
new file mode 100644
index 000000000000..5a19edc1a4d6
--- /dev/null
+++ b/test/std/re/re.alg/re.alg.match/inverted_character_classes.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+// UNSUPPORTED: c++98, c++03
+
+// Make sure that we correctly match inverted character classes.
+
+#include <cassert>
+#include <regex>
+
+
+int main() {
+ assert(std::regex_match("X", std::regex("[X]")));
+ assert(std::regex_match("X", std::regex("[XY]")));
+ assert(!std::regex_match("X", std::regex("[^X]")));
+ assert(!std::regex_match("X", std::regex("[^XY]")));
+
+ assert(std::regex_match("X", std::regex("[\\S]")));
+ assert(!std::regex_match("X", std::regex("[^\\S]")));
+
+ assert(!std::regex_match("X", std::regex("[\\s]")));
+ assert(std::regex_match("X", std::regex("[^\\s]")));
+
+ assert(std::regex_match("X", std::regex("[\\s\\S]")));
+ assert(std::regex_match("X", std::regex("[^Y\\s]")));
+ assert(!std::regex_match("X", std::regex("[^X\\s]")));
+
+ assert(std::regex_match("X", std::regex("[\\w]")));
+ assert(std::regex_match("_", std::regex("[\\w]")));
+ assert(!std::regex_match("X", std::regex("[^\\w]")));
+ assert(!std::regex_match("_", std::regex("[^\\w]")));
+
+ assert(!std::regex_match("X", std::regex("[\\W]")));
+ assert(!std::regex_match("_", std::regex("[\\W]")));
+ assert(std::regex_match("X", std::regex("[^\\W]")));
+ assert(std::regex_match("_", std::regex("[^\\W]")));
+}
diff --git a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
index d9c5172303fc..59673ec882f9 100644
--- a/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
@@ -63,8 +63,7 @@ test4()
assert((std::regex_match(target, smatch, regex)));
}
-int
-main()
+int main()
{
test1();
test2();
diff --git a/test/std/re/re.alg/re.alg.search/awk.pass.cpp b/test/std/re/re.alg/re.alg.search/awk.pass.cpp
index be0c74e9c779..85f38ec63dac 100644
--- a/test/std/re/re.alg/re.alg.search/awk.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/awk.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.search/basic.pass.cpp b/test/std/re/re.alg/re.alg.search/basic.pass.cpp
index 11982a26d003..82f051a071d8 100644
--- a/test/std/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/basic.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
index c41019542a55..a8ae1f550d71 100644
--- a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.search/extended.pass.cpp b/test/std/re/re.alg/re.alg.search/extended.pass.cpp
index 4a2e6647e079..6d95ad27502f 100644
--- a/test/std/re/re.alg/re.alg.search/extended.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/extended.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp b/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
index dd17d3519e3e..dc0b98558048 100644
--- a/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
@@ -18,7 +18,7 @@
#include <regex>
#include <cassert>
-#include "test_macros.h"
+
// PR34310
int main()
diff --git a/test/std/re/re.grammar/excessive_brace_count.pass.cpp b/test/std/re/re.grammar/excessive_brace_count.pass.cpp
index 597182e7e096..c4dade7dee41 100644
--- a/test/std/re/re.grammar/excessive_brace_count.pass.cpp
+++ b/test/std/re/re.grammar/excessive_brace_count.pass.cpp
@@ -9,7 +9,7 @@
// <regex>
// UNSUPPORTED: libcpp-no-exceptions
-// UNSUPPORTED: c++03
+// UNSUPPORTED: c++98, c++03
// the "n" in `a{n}` should be within the numeric limits.
diff --git a/test/std/re/re.results/re.results.const/copy.pass.cpp b/test/std/re/re.results/re.results.const/copy.pass.cpp
new file mode 100644
index 000000000000..ab0e388b5f43
--- /dev/null
+++ b/test/std/re/re.results/re.results.const/copy.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// class match_results<BidirectionalIterator, Allocator>
+
+// match_results(const match_results& m);
+
+#include <regex>
+#include <cassert>
+#include "test_macros.h"
+#include "test_allocator.h"
+
+template <class CharT, class Allocator>
+void
+test(const Allocator& a)
+{
+ typedef std::match_results<const CharT*, Allocator> SM;
+ SM m0(a);
+ SM m1(m0);
+
+ assert(m1.size() == m0.size());
+ assert(m1.str() == m0.str());
+ assert(m1.get_allocator() == m0.get_allocator());
+}
+
+int main()
+{
+ test<char> (std::allocator<std::sub_match<const char *> >());
+ test<wchar_t>(std::allocator<std::sub_match<const wchar_t *> >());
+
+ test<char> (test_allocator<std::sub_match<const char*> >(3));
+ test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3));
+}
diff --git a/test/std/re/re.results/re.results.const/copy_assign.pass.cpp b/test/std/re/re.results/re.results.const/copy_assign.pass.cpp
new file mode 100644
index 000000000000..d390d62f04a3
--- /dev/null
+++ b/test/std/re/re.results/re.results.const/copy_assign.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// class match_results<BidirectionalIterator, Allocator>
+
+// match_results& operator=(const match_results& m);
+
+#include <regex>
+#include <cassert>
+#include "test_macros.h"
+#include "test_allocator.h"
+
+template <class CharT, class Allocator>
+void
+test(const Allocator& a)
+{
+ typedef std::match_results<const CharT*, Allocator> SM;
+ SM m0(a);
+ SM m1;
+
+ m1 = m0;
+ assert(m1.size() == m0.size());
+ assert(m1.str() == m0.str());
+ if (std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value)
+ assert(m1.get_allocator() == m0.get_allocator());
+ else
+ assert(m1.get_allocator() == Allocator());
+}
+
+int main()
+{
+ test<char> (std::allocator<std::sub_match<const char *> >());
+ test<wchar_t>(std::allocator<std::sub_match<const wchar_t *> >());
+
+// test_allocator has POCCA -> false
+ test<char> (test_allocator<std::sub_match<const char*> >(3));
+ test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3));
+
+// other_allocator has POCCA -> true
+ test<char> (other_allocator<std::sub_match<const char*> >(3));
+ test<wchar_t>(other_allocator<std::sub_match<const wchar_t*> >(3));
+}
diff --git a/test/std/re/re.results/re.results.const/move.pass.cpp b/test/std/re/re.results/re.results.const/move.pass.cpp
new file mode 100644
index 000000000000..2c2233c76127
--- /dev/null
+++ b/test/std/re/re.results/re.results.const/move.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+// <regex>
+
+// class match_results<BidirectionalIterator, Allocator>
+
+// match_results(match_results&& m) noexcept;
+//
+// Additionally, the stored Allocator value is move constructed from m.get_allocator().
+
+#include <regex>
+#include <cassert>
+#include "test_macros.h"
+#include "test_allocator.h"
+
+template <class CharT, class Allocator>
+void
+test(const Allocator& a)
+{
+ typedef std::match_results<const CharT*, Allocator> SM;
+ ASSERT_NOEXCEPT(SM(std::declval<SM&&>()));
+
+ SM m0(a);
+ assert(m0.get_allocator() == a);
+
+ SM m1(std::move(m0));
+ assert(m1.size() == 0);
+ assert(m1.str() == std::basic_string<CharT>());
+ assert(m1.get_allocator() == a);
+}
+
+int main()
+{
+ test<char> (std::allocator<std::sub_match<const char *> >());
+ test<wchar_t>(std::allocator<std::sub_match<const wchar_t *> >());
+
+ test<char> (test_allocator<std::sub_match<const char*> >(3));
+ assert(test_alloc_base::moved == 1);
+ test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3));
+ assert(test_alloc_base::moved == 2);
+}
diff --git a/test/std/re/re.results/re.results.const/move_assign.pass.cpp b/test/std/re/re.results/re.results.const/move_assign.pass.cpp
new file mode 100644
index 000000000000..2d2e81b17237
--- /dev/null
+++ b/test/std/re/re.results/re.results.const/move_assign.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03
+
+// <regex>
+
+// class match_results<BidirectionalIterator, Allocator>
+
+// match_results& operator=(match_results&& m);
+
+#include <regex>
+#include <cassert>
+#include "test_macros.h"
+#include "test_allocator.h"
+
+template <class CharT, class Allocator>
+void
+test(const Allocator& a)
+{
+ typedef std::match_results<const CharT*, Allocator> SM;
+ SM m0(a);
+ SM m1;
+
+ m1 = std::move(m0);
+ assert(m1.size() == 0);
+ assert(m1.str() == std::basic_string<CharT>());
+ if (std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value)
+ assert(m1.get_allocator() == a);
+ else
+ assert(m1.get_allocator() == Allocator());
+}
+
+int main()
+{
+ test<char> (std::allocator<std::sub_match<const char *> >());
+ test<wchar_t>(std::allocator<std::sub_match<const wchar_t *> >());
+
+// test_allocator has POCMA -> false
+ test<char> (test_allocator<std::sub_match<const char*> >(3));
+ test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3));
+
+// other_allocator has POCMA -> true
+ test<char> (other_allocator<std::sub_match<const char*> >(3));
+ test<wchar_t>(other_allocator<std::sub_match<const wchar_t*> >(3));
+}
diff --git a/test/std/re/re.traits/lookup_collatename.pass.cpp b/test/std/re/re.traits/lookup_collatename.pass.cpp
index 3aeed7bddf75..ef5c14257ac0 100644
--- a/test/std/re/re.traits/lookup_collatename.pass.cpp
+++ b/test/std/re/re.traits/lookup_collatename.pass.cpp
@@ -6,6 +6,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.traits/transform.pass.cpp b/test/std/re/re.traits/transform.pass.cpp
index 57e6b753abef..7563b395216f 100644
--- a/test/std/re/re.traits/transform.pass.cpp
+++ b/test/std/re/re.traits/transform.pass.cpp
@@ -7,6 +7,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.traits/transform_primary.pass.cpp b/test/std/re/re.traits/transform_primary.pass.cpp
index 03b4f3985a60..2dd8ed247cb4 100644
--- a/test/std/re/re.traits/transform_primary.pass.cpp
+++ b/test/std/re/re.traits/transform_primary.pass.cpp
@@ -7,6 +7,9 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// NetBSD does not support LC_COLLATE at the moment
+// XFAIL: netbsd
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/test/std/re/re.traits/translate_nocase.pass.cpp b/test/std/re/re.traits/translate_nocase.pass.cpp
index 33d365a9ede3..601da6b862ad 100644
--- a/test/std/re/re.traits/translate_nocase.pass.cpp
+++ b/test/std/re/re.traits/translate_nocase.pass.cpp
@@ -16,12 +16,6 @@
// REQUIRES: locale.en_US.UTF-8
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
-
-// TODO: investigation needed
-// XFAIL: linux-gnu
-
#include <regex>
#include <cassert>
@@ -47,8 +41,6 @@ int main()
assert(t.translate_nocase('.') == '.');
assert(t.translate_nocase('a') == 'a');
assert(t.translate_nocase('1') == '1');
- assert(t.translate_nocase('\xDA') == '\xFA');
- assert(t.translate_nocase('\xFA') == '\xFA');
}
{
std::regex_traits<wchar_t> t;
diff --git a/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
index 01f01218999d..e6f3d53a84e1 100644
--- a/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
+++ b/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
@@ -23,6 +23,9 @@ int main() {
{
test_hash_enabled_for_type<std::string>();
test_hash_enabled_for_type<std::wstring>();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test_hash_enabled_for_type<std::u8string>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test_hash_enabled_for_type<std::u16string>();
test_hash_enabled_for_type<std::u32string>();
diff --git a/test/std/strings/basic.string.hash/strings.pass.cpp b/test/std/strings/basic.string.hash/strings.pass.cpp
index d74e485752fc..449ad8f1139b 100644
--- a/test/std/strings/basic.string.hash/strings.pass.cpp
+++ b/test/std/strings/basic.string.hash/strings.pass.cpp
@@ -44,6 +44,9 @@ test()
int main()
{
test<std::string>();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test<std::u8string>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<std::u16string>();
test<std::u32string>();
diff --git a/test/std/strings/basic.string.literals/literal.pass.cpp b/test/std/strings/basic.string.literals/literal.pass.cpp
index d121e25ba270..cbb03ef61f11 100644
--- a/test/std/strings/basic.string.literals/literal.pass.cpp
+++ b/test/std/strings/basic.string.literals/literal.pass.cpp
@@ -13,36 +13,46 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string u8string;
+#else
+ typedef std::string u8string;
+#endif
+
+
int main()
{
using namespace std::literals::string_literals;
static_assert ( std::is_same<decltype( "Hi"s), std::string>::value, "" );
- static_assert ( std::is_same<decltype( u8"Hi"s), std::string>::value, "" );
+ static_assert ( std::is_same<decltype( u8"Hi"s), u8string>::value, "" );
static_assert ( std::is_same<decltype( L"Hi"s), std::wstring>::value, "" );
static_assert ( std::is_same<decltype( u"Hi"s), std::u16string>::value, "" );
static_assert ( std::is_same<decltype( U"Hi"s), std::u32string>::value, "" );
std::string foo;
std::wstring Lfoo;
+ u8string u8foo;
std::u16string ufoo;
std::u32string Ufoo;
- foo = ""s; assert( foo.size() == 0);
- foo = u8""s; assert( foo.size() == 0);
- Lfoo = L""s; assert(Lfoo.size() == 0);
- ufoo = u""s; assert(ufoo.size() == 0);
- Ufoo = U""s; assert(Ufoo.size() == 0);
-
- foo = " "s; assert( foo.size() == 1);
- foo = u8" "s; assert( foo.size() == 1);
- Lfoo = L" "s; assert(Lfoo.size() == 1);
- ufoo = u" "s; assert(ufoo.size() == 1);
- Ufoo = U" "s; assert(Ufoo.size() == 1);
-
- foo = "ABC"s; assert( foo == "ABC"); assert( foo == std::string ( "ABC"));
- foo = u8"ABC"s; assert( foo == u8"ABC"); assert( foo == std::string (u8"ABC"));
- Lfoo = L"ABC"s; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring ( L"ABC"));
- ufoo = u"ABC"s; assert(ufoo == u"ABC"); assert(ufoo == std::u16string( u"ABC"));
- Ufoo = U"ABC"s; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string( U"ABC"));
+ foo = ""s; assert( foo.size() == 0);
+ u8foo = u8""s; assert(u8foo.size() == 0);
+ Lfoo = L""s; assert( Lfoo.size() == 0);
+ ufoo = u""s; assert( ufoo.size() == 0);
+ Ufoo = U""s; assert( Ufoo.size() == 0);
+
+ foo = " "s; assert( foo.size() == 1);
+ u8foo = u8" "s; assert(u8foo.size() == 1);
+ Lfoo = L" "s; assert( Lfoo.size() == 1);
+ ufoo = u" "s; assert( ufoo.size() == 1);
+ Ufoo = U" "s; assert( Ufoo.size() == 1);
+
+ foo = "ABC"s; assert( foo == "ABC"); assert( foo == std::string ( "ABC"));
+ u8foo = u8"ABC"s; assert(u8foo == u8"ABC"); assert(u8foo == u8string (u8"ABC"));
+ Lfoo = L"ABC"s; assert( Lfoo == L"ABC"); assert( Lfoo == std::wstring ( L"ABC"));
+ ufoo = u"ABC"s; assert( ufoo == u"ABC"); assert( ufoo == std::u16string( u"ABC"));
+ Ufoo = U"ABC"s; assert( Ufoo == U"ABC"); assert( Ufoo == std::u32string( U"ABC"));
}
diff --git a/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp b/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
index f36f53e656db..3dfd32aebaa7 100644
--- a/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
+++ b/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
@@ -20,6 +20,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "min_allocator.h"
diff --git a/test/std/strings/basic.string/string.capacity/reserve.pass.cpp b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
index 7210152ea3cb..8b9dc13db838 100644
--- a/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
+++ b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
@@ -9,7 +9,9 @@
// <string>
-// void reserve(size_type res_arg=0);
+// Split into two calls for C++20
+// void reserve();
+// void reserve(size_type res_arg);
#include <string>
#include <stdexcept>
@@ -44,6 +46,9 @@ test(S s, typename S::size_type res_arg)
assert(s == s0);
assert(s.capacity() >= res_arg);
assert(s.capacity() >= s.size());
+#if TEST_STD_VER > 17
+ assert(s.capacity() >= old_cap); // resize never shrinks as of P0966
+#endif
}
#ifndef TEST_HAS_NO_EXCEPTIONS
else
@@ -90,6 +95,7 @@ int main()
test(s, 10);
test(s, 50);
test(s, 100);
+ test(s, 1000);
test(s, S::npos);
}
}
@@ -121,6 +127,7 @@ int main()
test(s, 10);
test(s, 50);
test(s, 100);
+ test(s, 1000);
test(s, S::npos);
}
}
diff --git a/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
index df1e99e0147f..a1f3c4b51f94 100644
--- a/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
@@ -72,6 +72,18 @@ int main()
assert(s1.size() == sv.size());
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ {
+ std::u8string_view sv = u8"12345678901234";
+ std::basic_string s1{sv, min_allocator<char8_t>{}};
+ using S = decltype(s1); // what type did we get?
+ static_assert(std::is_same_v<S::value_type, char8_t>, "");
+ static_assert(std::is_same_v<S::traits_type, std::char_traits<char8_t>>, "");
+ static_assert(std::is_same_v<S::allocator_type, min_allocator<char8_t>>, "");
+ assert(s1.size() == sv.size());
+ assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
+ }
+#endif
{
std::u16string_view sv = u"12345678901234";
std::basic_string s1{sv, min_allocator<char16_t>{}};
diff --git a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp
index f79e43f6a6b0..17cb7dd167e1 100644
--- a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp
+++ b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.fail.cpp
@@ -25,7 +25,7 @@
// const Allocator& = Allocator())
// -> basic_string<charT, traits, Allocator>;
//
-// A size_type parameter type in a basic_string deduction guide refers to the size_type
+// A size_type parameter type in a basic_string deduction guide refers to the size_type
// member type of the type deduced by the deduction guide.
//
// The deduction guide shall not participate in overload resolution if Allocator
diff --git a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
index d9561d22b882..fd9684e1fa99 100644
--- a/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
@@ -25,7 +25,7 @@
// const Allocator& = Allocator())
// -> basic_string<charT, traits, Allocator>;
//
-// A size_type parameter type in a basic_string deduction guide refers to the size_type
+// A size_type parameter type in a basic_string deduction guide refers to the size_type
// member type of the type deduced by the deduction guide.
//
// The deduction guide shall not participate in overload resolution if Allocator
@@ -76,6 +76,18 @@ int main()
assert(s1.size() == 4);
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ {
+ std::u8string_view sv = u8"12345678901234";
+ std::basic_string s1{sv, 0, 4, min_allocator<char8_t>{}};
+ using S = decltype(s1); // what type did we get?
+ static_assert(std::is_same_v<S::value_type, char8_t>, "");
+ static_assert(std::is_same_v<S::traits_type, std::char_traits<char8_t>>, "");
+ static_assert(std::is_same_v<S::allocator_type, min_allocator<char8_t>>, "");
+ assert(s1.size() == 4);
+ assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
+ }
+#endif
{
std::u16string_view sv = u"12345678901234";
std::basic_string s1{sv, 0, 4, min_allocator<char16_t>{}};
diff --git a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
index 9466f1135102..8bc6e4fb2565 100644
--- a/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
+++ b/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
@@ -47,6 +47,20 @@ int main()
assert ( !(ii1 != cii ));
}
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ {
+ typedef std::u8string C;
+ C::iterator ii1{}, ii2{};
+ C::iterator ii4 = ii1;
+ C::const_iterator cii{};
+ assert ( ii1 == ii2 );
+ assert ( ii1 == ii4 );
+ assert ( ii1 == cii );
+ assert ( !(ii1 != ii2 ));
+ assert ( !(ii1 != cii ));
+ }
+#endif
+
{ // N3644 testing
typedef std::u16string C;
C::iterator ii1{}, ii2{};
diff --git a/test/std/strings/c.strings/cctype.pass.cpp b/test/std/strings/c.strings/cctype.pass.cpp
index 027fbcd469d5..695c5e40d7b0 100644
--- a/test/std/strings/c.strings/cctype.pass.cpp
+++ b/test/std/strings/c.strings/cctype.pass.cpp
@@ -13,6 +13,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
#ifdef isalnum
#error isalnum defined
#endif
@@ -71,33 +73,34 @@
int main()
{
- static_assert((std::is_same<decltype(std::isalnum(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isalpha(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isblank(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::iscntrl(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isdigit(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isgraph(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::islower(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isprint(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::ispunct(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isspace(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isupper(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::isxdigit(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::tolower(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::toupper(0)), int>::value), "");
-
- assert(std::isalnum('a'));
- assert(std::isalpha('a'));
- assert(std::isblank(' '));
+
+ ASSERT_SAME_TYPE(int, decltype(std::isalnum(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isalpha(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isblank(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::iscntrl(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isdigit(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isgraph(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::islower(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isprint(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::ispunct(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isspace(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isupper(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::isxdigit(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::tolower(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::toupper(0)));
+
+ assert( std::isalnum('a'));
+ assert( std::isalpha('a'));
+ assert( std::isblank(' '));
assert(!std::iscntrl(' '));
assert(!std::isdigit('a'));
- assert(std::isgraph('a'));
- assert(std::islower('a'));
- assert(std::isprint('a'));
+ assert( std::isgraph('a'));
+ assert( std::islower('a'));
+ assert( std::isprint('a'));
assert(!std::ispunct('a'));
assert(!std::isspace('a'));
assert(!std::isupper('a'));
- assert(std::isxdigit('a'));
- assert(std::tolower('A') == 'a');
- assert(std::toupper('a') == 'A');
+ assert( std::isxdigit('a'));
+ assert( std::tolower('A') == 'a');
+ assert( std::toupper('a') == 'A');
}
diff --git a/test/std/strings/c.strings/cstring.pass.cpp b/test/std/strings/c.strings/cstring.pass.cpp
index 63f86d350610..22952e0f2bc1 100644
--- a/test/std/strings/c.strings/cstring.pass.cpp
+++ b/test/std/strings/c.strings/cstring.pass.cpp
@@ -12,6 +12,8 @@
#include <cstring>
#include <type_traits>
+#include "test_macros.h"
+
#ifndef NULL
#error NULL not defined
#endif
@@ -23,39 +25,40 @@ int main()
const void* vpc = 0;
char* cp = 0;
const char* cpc = 0;
- static_assert((std::is_same<decltype(std::memcpy(vp, vpc, s)), void*>::value), "");
- static_assert((std::is_same<decltype(std::memmove(vp, vpc, s)), void*>::value), "");
- static_assert((std::is_same<decltype(std::strcpy(cp, cpc)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strncpy(cp, cpc, s)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strcat(cp, cpc)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strncat(cp, cpc, s)), char*>::value), "");
- static_assert((std::is_same<decltype(std::memcmp(vpc, vpc, s)), int>::value), "");
- static_assert((std::is_same<decltype(std::strcmp(cpc, cpc)), int>::value), "");
- static_assert((std::is_same<decltype(std::strncmp(cpc, cpc, s)), int>::value), "");
- static_assert((std::is_same<decltype(std::strcoll(cpc, cpc)), int>::value), "");
- static_assert((std::is_same<decltype(std::strxfrm(cp, cpc, s)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::memchr(vp, 0, s)), void*>::value), "");
- static_assert((std::is_same<decltype(std::strchr(cp, 0)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strcspn(cpc, cpc)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::strpbrk(cp, cpc)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strrchr(cp, 0)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strspn(cpc, cpc)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::strstr(cp, cpc)), char*>::value), "");
+
+ ASSERT_SAME_TYPE(void*, decltype(std::memcpy(vp, vpc, s)));
+ ASSERT_SAME_TYPE(void*, decltype(std::memmove(vp, vpc, s)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strcpy(cp, cpc)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strncpy(cp, cpc, s)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strcat(cp, cpc)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strncat(cp, cpc, s)));
+ ASSERT_SAME_TYPE(int, decltype(std::memcmp(vpc, vpc, s)));
+ ASSERT_SAME_TYPE(int, decltype(std::strcmp(cpc, cpc)));
+ ASSERT_SAME_TYPE(int, decltype(std::strncmp(cpc, cpc, s)));
+ ASSERT_SAME_TYPE(int, decltype(std::strcoll(cpc, cpc)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::strxfrm(cp, cpc, s)));
+ ASSERT_SAME_TYPE(void*, decltype(std::memchr(vp, 0, s)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strchr(cp, 0)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::strcspn(cpc, cpc)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strpbrk(cp, cpc)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strrchr(cp, 0)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::strspn(cpc, cpc)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strstr(cp, cpc)));
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
- static_assert((std::is_same<decltype(std::strtok(cp, cpc)), char*>::value), "");
+ ASSERT_SAME_TYPE(char*, decltype(std::strtok(cp, cpc)));
#endif
- static_assert((std::is_same<decltype(std::memset(vp, 0, s)), void*>::value), "");
- static_assert((std::is_same<decltype(std::strerror(0)), char*>::value), "");
- static_assert((std::is_same<decltype(std::strlen(cpc)), std::size_t>::value), "");
+ ASSERT_SAME_TYPE(void*, decltype(std::memset(vp, 0, s)));
+ ASSERT_SAME_TYPE(char*, decltype(std::strerror(0)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::strlen(cpc)));
// These tests fail on systems whose C library doesn't provide a correct overload
// set for strchr, strpbrk, strrchr, strstr, and memchr, unless the compiler is
// a suitably recent version of Clang.
#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD)
- static_assert((std::is_same<decltype(std::memchr(vpc, 0, s)), const void*>::value), "");
- static_assert((std::is_same<decltype(std::strchr(cpc, 0)), const char*>::value), "");
- static_assert((std::is_same<decltype(std::strpbrk(cpc, cpc)), const char*>::value), "");
- static_assert((std::is_same<decltype(std::strrchr(cpc, 0)), const char*>::value), "");
- static_assert((std::is_same<decltype(std::strstr(cpc, cpc)), const char*>::value), "");
+ ASSERT_SAME_TYPE(const void*, decltype(std::memchr(vpc, 0, s)));
+ ASSERT_SAME_TYPE(const char*, decltype(std::strchr(cpc, 0)));
+ ASSERT_SAME_TYPE(const char*, decltype(std::strpbrk(cpc, cpc)));
+ ASSERT_SAME_TYPE(const char*, decltype(std::strrchr(cpc, 0)));
+ ASSERT_SAME_TYPE(const char*, decltype(std::strstr(cpc, cpc)));
#endif
}
diff --git a/test/std/strings/c.strings/cuchar.pass.cpp b/test/std/strings/c.strings/cuchar.pass.cpp
index 022c656e8a27..f14eda511809 100644
--- a/test/std/strings/c.strings/cuchar.pass.cpp
+++ b/test/std/strings/c.strings/cuchar.pass.cpp
@@ -13,6 +13,8 @@
#include <cuchar>
+#include "test_macros.h"
+
int main()
{
}
diff --git a/test/std/strings/c.strings/cwchar.pass.cpp b/test/std/strings/c.strings/cwchar.pass.cpp
index 2b7c3c465f6d..116da936e0f5 100644
--- a/test/std/strings/c.strings/cwchar.pass.cpp
+++ b/test/std/strings/c.strings/cwchar.pass.cpp
@@ -10,9 +10,12 @@
// <cwchar>
#include <cwchar>
+#include <ctime>
#include <cstdarg>
#include <type_traits>
+#include "test_macros.h"
+
#ifndef NULL
#error NULL not defined
#endif
@@ -50,80 +53,80 @@ int main()
((void)ns); // Prevent unused warning
((void)ws); // Prevent unused warning
- static_assert((std::is_same<decltype(std::fwprintf(fp, L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::fwscanf(fp, L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::swprintf(ws, s, L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::swscanf(L"", L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::vfwprintf(fp, L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vfwscanf(fp, L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vswprintf(ws, s, L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vswscanf(L"", L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::fgetwc(fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::fgetws(ws, 0, fp)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::fputwc(L' ', fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::fputws(L"", fp)), int>::value), "");
- static_assert((std::is_same<decltype(std::fwide(fp, 0)), int>::value), "");
- static_assert((std::is_same<decltype(std::getwc(fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::putwc(L' ', fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::ungetwc(L' ', fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::wcstod(L"", (wchar_t**)0)), double>::value), "");
- static_assert((std::is_same<decltype(std::wcstof(L"", (wchar_t**)0)), float>::value), "");
- static_assert((std::is_same<decltype(std::wcstold(L"", (wchar_t**)0)), long double>::value), "");
- static_assert((std::is_same<decltype(std::wcstol(L"", (wchar_t**)0, 0)), long>::value), "");
- static_assert((std::is_same<decltype(std::wcstoll(L"", (wchar_t**)0, 0)), long long>::value), "");
- static_assert((std::is_same<decltype(std::wcstoul(L"", (wchar_t**)0, 0)), unsigned long>::value), "");
- static_assert((std::is_same<decltype(std::wcstoull(L"", (wchar_t**)0, 0)), unsigned long long>::value), "");
- static_assert((std::is_same<decltype(std::wcscpy(ws, L"")), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsncpy(ws, L"", s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcscat(ws, L"")), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsncat(ws, L"", s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcscmp(L"", L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::wcscoll(L"", L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::wcsncmp(L"", L"", s)), int>::value), "");
- static_assert((std::is_same<decltype(std::wcsxfrm(ws, L"", s)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcschr((wchar_t*)0, L' ')), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcscspn(L"", L"")), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcslen(L"")), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsspn(L"", L"")), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcsstr((wchar_t*)0, L"")), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wmemcmp(L"", L"", s)), int>::value), "");
- static_assert((std::is_same<decltype(std::wmemcpy(ws, L"", s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wmemmove(ws, L"", s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wmemset(ws, L' ', s)), wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsftime(ws, s, L"", tm)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::btowc(0)), wint_t>::value), "");
- static_assert((std::is_same<decltype(std::wctob(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::mbsinit(&mb)), int>::value), "");
- static_assert((std::is_same<decltype(std::mbrlen("", s, &mb)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::mbrtowc(ws, "", s, &mb)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcrtomb(ns, L' ', &mb)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::mbsrtowcs(ws, (const char**)0, s, &mb)), std::size_t>::value), "");
- static_assert((std::is_same<decltype(std::wcsrtombs(ns, (const wchar_t**)0, s, &mb)), std::size_t>::value), "");
+ ASSERT_SAME_TYPE(int, decltype(std::fwprintf(fp, L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::fwscanf(fp, L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::swprintf(ws, s, L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::swscanf(L"", L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::vfwprintf(fp, L"", va)));
+ ASSERT_SAME_TYPE(int, decltype(std::vfwscanf(fp, L"", va)));
+ ASSERT_SAME_TYPE(int, decltype(std::vswprintf(ws, s, L"", va)));
+ ASSERT_SAME_TYPE(int, decltype(std::vswscanf(L"", L"", va)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::fgetwc(fp)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::fgetws(ws, 0, fp)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::fputwc(L' ', fp)));
+ ASSERT_SAME_TYPE(int, decltype(std::fputws(L"", fp)));
+ ASSERT_SAME_TYPE(int, decltype(std::fwide(fp, 0)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::getwc(fp)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::putwc(L' ', fp)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::ungetwc(L' ', fp)));
+ ASSERT_SAME_TYPE(double, decltype(std::wcstod(L"", (wchar_t**)0)));
+ ASSERT_SAME_TYPE(float, decltype(std::wcstof(L"", (wchar_t**)0)));
+ ASSERT_SAME_TYPE(long double, decltype(std::wcstold(L"", (wchar_t**)0)));
+ ASSERT_SAME_TYPE(long, decltype(std::wcstol(L"", (wchar_t**)0, 0)));
+ ASSERT_SAME_TYPE(long long, decltype(std::wcstoll(L"", (wchar_t**)0, 0)));
+ ASSERT_SAME_TYPE(unsigned long, decltype(std::wcstoul(L"", (wchar_t**)0, 0)));
+ ASSERT_SAME_TYPE(unsigned long long, decltype(std::wcstoull(L"", (wchar_t**)0, 0)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcscpy(ws, L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsncpy(ws, L"", s)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcscat(ws, L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsncat(ws, L"", s)));
+ ASSERT_SAME_TYPE(int, decltype(std::wcscmp(L"", L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::wcscoll(L"", L"")));
+ ASSERT_SAME_TYPE(int, decltype(std::wcsncmp(L"", L"", s)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsxfrm(ws, L"", s)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcschr((wchar_t*)0, L' ')));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcscspn(L"", L"")));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcslen(L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcspbrk((wchar_t*)0, L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsrchr((wchar_t*)0, L' ')));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsspn(L"", L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcsstr((wchar_t*)0, L"")));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wcstok(ws, L"", (wchar_t**)0)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemchr((wchar_t*)0, L' ', s)));
+ ASSERT_SAME_TYPE(int, decltype(std::wmemcmp(L"", L"", s)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemcpy(ws, L"", s)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemmove(ws, L"", s)));
+ ASSERT_SAME_TYPE(wchar_t*, decltype(std::wmemset(ws, L' ', s)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsftime(ws, s, L"", tm)));
+ ASSERT_SAME_TYPE(wint_t, decltype(std::btowc(0)));
+ ASSERT_SAME_TYPE(int, decltype(std::wctob(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::mbsinit(&mb)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::mbrlen("", s, &mb)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::mbrtowc(ws, "", s, &mb)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcrtomb(ns, L' ', &mb)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::mbsrtowcs(ws, (const char**)0, s, &mb)));
+ ASSERT_SAME_TYPE(std::size_t, decltype(std::wcsrtombs(ns, (const wchar_t**)0, s, &mb)));
// These tests fail on systems whose C library doesn't provide a correct overload
// set for wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr, unless the compiler is
// a suitably recent version of Clang.
#if !defined(__APPLE__) || defined(_LIBCPP_PREFERRED_OVERLOAD)
- static_assert((std::is_same<decltype(std::wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), "");
- static_assert((std::is_same<decltype(std::wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), "");
+ ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcschr((const wchar_t*)0, L' ')));
+ ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcspbrk((const wchar_t*)0, L"")));
+ ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcsrchr((const wchar_t*)0, L' ')));
+ ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wcsstr((const wchar_t*)0, L"")));
+ ASSERT_SAME_TYPE(const wchar_t*, decltype(std::wmemchr((const wchar_t*)0, L' ', s)));
#endif
#ifndef _LIBCPP_HAS_NO_STDIN
- static_assert((std::is_same<decltype(std::getwchar()), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::vwscanf(L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::wscanf(L"")), int>::value), "");
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::getwchar()));
+ ASSERT_SAME_TYPE(int, decltype(std::vwscanf(L"", va)));
+ ASSERT_SAME_TYPE(int, decltype(std::wscanf(L"")));
#endif
#ifndef _LIBCPP_HAS_NO_STDOUT
- static_assert((std::is_same<decltype(std::putwchar(L' ')), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::vwprintf(L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::wprintf(L"")), int>::value), "");
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::putwchar(L' ')));
+ ASSERT_SAME_TYPE(int, decltype(std::vwprintf(L"", va)));
+ ASSERT_SAME_TYPE(int, decltype(std::wprintf(L"")));
#endif
}
diff --git a/test/std/strings/c.strings/cwctype.pass.cpp b/test/std/strings/c.strings/cwctype.pass.cpp
index 6d66415abdc1..14f730b15b75 100644
--- a/test/std/strings/c.strings/cwctype.pass.cpp
+++ b/test/std/strings/c.strings/cwctype.pass.cpp
@@ -12,6 +12,9 @@
#include <cwctype>
#include <type_traits>
+#include "test_macros.h"
+
+
#ifndef WEOF
#error WEOF not defined
#endif
@@ -91,24 +94,24 @@
int main()
{
std::wint_t w = 0;
- std::wctrans_t wctr = 0;
- std::wctype_t wct = 0;
- static_assert((std::is_same<decltype(std::iswalnum(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswalpha(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswblank(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswcntrl(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswdigit(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswgraph(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswlower(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswprint(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswpunct(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswspace(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswupper(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswxdigit(w)), int>::value), "");
- static_assert((std::is_same<decltype(std::iswctype(w, wct)), int>::value), "");
- static_assert((std::is_same<decltype(std::wctype("")), std::wctype_t>::value), "");
- static_assert((std::is_same<decltype(std::towlower(w)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::towupper(w)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::towctrans(w, wctr)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::wctrans("")), std::wctrans_t>::value), "");
+ ASSERT_SAME_TYPE(int, decltype(std::iswalnum(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswalpha(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswblank(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswcntrl(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswdigit(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswgraph(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswlower(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswprint(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswpunct(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswspace(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswupper(w)));
+ ASSERT_SAME_TYPE(int, decltype(std::iswxdigit(w)));
+
+ ASSERT_SAME_TYPE(int, decltype(std::iswctype(w, std::wctype_t())));
+
+ ASSERT_SAME_TYPE(std::wctype_t, decltype(std::wctype("")));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::towlower(w)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::towupper(w)));
+ ASSERT_SAME_TYPE(std::wint_t, decltype(std::towctrans(w, std::wctrans_t())));
+ ASSERT_SAME_TYPE(std::wctrans_t, decltype(std::wctrans("")));
}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp
new file mode 100644
index 000000000000..e293115faec6
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign2.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr void assign(char_type& c1, const char_type& c2);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+constexpr bool test_constexpr()
+{
+ char8_t c = u'1';
+ std::char_traits<char8_t>::assign(c, u'a');
+ return c == u'a';
+}
+
+int main()
+{
+ char8_t c = u8'\0';
+ std::char_traits<char8_t>::assign(c, u8'a');
+ assert(c == u8'a');
+
+ static_assert(test_constexpr(), "");
+}
+#else
+int main () {}
+#endif
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp
new file mode 100644
index 000000000000..d1fab485c38b
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/assign3.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static char_type* assign(char_type* s, size_t n, char_type a);
+
+#include <string>
+#include <cassert>
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ char8_t s2[3] = {0};
+ assert(std::char_traits<char8_t>::assign(s2, 3, char8_t(5)) == s2);
+ assert(s2[0] == char8_t(5));
+ assert(s2[1] == char8_t(5));
+ assert(s2[2] == char8_t(5));
+ assert(std::char_traits<char8_t>::assign(NULL, 0, char8_t(5)) == NULL);
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp
new file mode 100644
index 000000000000..5ab1c9f0be08
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+constexpr bool test_constexpr()
+{
+ return std::char_traits<char8_t>::compare(u8"123", u8"223", 3) < 0
+ && std::char_traits<char8_t>::compare(u8"223", u8"123", 3) > 0
+ && std::char_traits<char8_t>::compare(u8"123", u8"123", 3) == 0;
+}
+
+
+int main()
+{
+ assert(std::char_traits<char8_t>::compare(u8"", u8"", 0) == 0);
+ assert(std::char_traits<char8_t>::compare(NULL, NULL, 0) == 0);
+
+ assert(std::char_traits<char8_t>::compare(u8"1", u8"1", 1) == 0);
+ assert(std::char_traits<char8_t>::compare(u8"1", u8"2", 1) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"2", u8"1", 1) > 0);
+
+ assert(std::char_traits<char8_t>::compare(u8"12", u8"12", 2) == 0);
+ assert(std::char_traits<char8_t>::compare(u8"12", u8"13", 2) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"12", u8"22", 2) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"13", u8"12", 2) > 0);
+ assert(std::char_traits<char8_t>::compare(u8"22", u8"12", 2) > 0);
+
+ assert(std::char_traits<char8_t>::compare(u8"123", u8"123", 3) == 0);
+ assert(std::char_traits<char8_t>::compare(u8"123", u8"223", 3) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"123", u8"133", 3) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"123", u8"124", 3) < 0);
+ assert(std::char_traits<char8_t>::compare(u8"223", u8"123", 3) > 0);
+ assert(std::char_traits<char8_t>::compare(u8"133", u8"123", 3) > 0);
+ assert(std::char_traits<char8_t>::compare(u8"124", u8"123", 3) > 0);
+
+ static_assert(test_constexpr(), "" );
+}
+#else
+int main () {}
+#endif
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp
new file mode 100644
index 000000000000..74d51667d568
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/copy.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
+#include <string>
+#include <cassert>
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ char8_t s1[] = {1, 2, 3};
+ char8_t s2[3] = {0};
+ assert(std::char_traits<char8_t>::copy(s2, s1, 3) == s2);
+ assert(s2[0] == char8_t(1));
+ assert(s2[1] == char8_t(2));
+ assert(s2[2] == char8_t(3));
+ assert(std::char_traits<char8_t>::copy(NULL, s1, 0) == NULL);
+ assert(std::char_traits<char8_t>::copy(s1, NULL, 0) == s1);
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp
new file mode 100644
index 000000000000..c48e3aedda39
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr int_type eof();
+
+#include <string>
+#include <cassert>
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ std::char_traits<char8_t>::int_type i = std::char_traits<char8_t>::eof();
+ ((void)i); // Prevent unused warning
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp
new file mode 100644
index 000000000000..2b7d793c7455
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr bool eq(char_type c1, char_type c2);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert( std::char_traits<char8_t>::eq(u8'a', u8'a'));
+ assert(!std::char_traits<char8_t>::eq(u8'a', u8'A'));
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp
new file mode 100644
index 000000000000..15e645e3a5da
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eq_int_type.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr bool eq_int_type(int_type c1, int_type c2);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert( std::char_traits<char8_t>::eq_int_type(u8'a', u8'a'));
+ assert(!std::char_traits<char8_t>::eq_int_type(u8'a', u8'A'));
+ assert(!std::char_traits<char8_t>::eq_int_type(std::char_traits<char8_t>::eof(), u8'A'));
+ assert( std::char_traits<char8_t>::eq_int_type(std::char_traits<char8_t>::eof(),
+ std::char_traits<char8_t>::eof()));
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp
new file mode 100644
index 000000000000..f35816659d03
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/find.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+constexpr bool test_constexpr()
+{
+ constexpr const char8_t *p = u8"123";
+ return std::char_traits<char8_t>::find(p, 3, u8'1') == p
+ && std::char_traits<char8_t>::find(p, 3, u8'2') == p + 1
+ && std::char_traits<char8_t>::find(p, 3, u8'3') == p + 2
+ && std::char_traits<char8_t>::find(p, 3, u8'4') == nullptr;
+}
+
+int main()
+{
+ char8_t s1[] = {1, 2, 3};
+ assert(std::char_traits<char8_t>::find(s1, 3, char8_t(1)) == s1);
+ assert(std::char_traits<char8_t>::find(s1, 3, char8_t(2)) == s1+1);
+ assert(std::char_traits<char8_t>::find(s1, 3, char8_t(3)) == s1+2);
+ assert(std::char_traits<char8_t>::find(s1, 3, char8_t(4)) == 0);
+ assert(std::char_traits<char8_t>::find(s1, 3, char8_t(0)) == 0);
+ assert(std::char_traits<char8_t>::find(NULL, 0, char8_t(0)) == 0);
+
+ static_assert(test_constexpr(), "" );
+}
+#else
+int main () {}
+#endif
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp
new file mode 100644
index 000000000000..f200c2332788
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/length.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr size_t length(const char_type* s);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+constexpr bool test_constexpr()
+{
+ return std::char_traits<char8_t>::length(u8"") == 0
+ && std::char_traits<char8_t>::length(u8"abcd") == 4;
+}
+
+int main()
+{
+ assert(std::char_traits<char8_t>::length(u8"") == 0);
+ assert(std::char_traits<char8_t>::length(u8"a") == 1);
+ assert(std::char_traits<char8_t>::length(u8"aa") == 2);
+ assert(std::char_traits<char8_t>::length(u8"aaa") == 3);
+ assert(std::char_traits<char8_t>::length(u8"aaaa") == 4);
+
+ static_assert(test_constexpr(), "");
+}
+#else
+int main() { }
+#endif
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp
new file mode 100644
index 000000000000..73c703f7734f
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/lt.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr bool lt(char_type c1, char_type c2);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert(!std::char_traits<char8_t>::lt(u8'a', u8'a'));
+ assert( std::char_traits<char8_t>::lt(u8'A', u8'a'));
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp
new file mode 100644
index 000000000000..688e559321b7
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/move.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static char_type* move(char_type* s1, const char_type* s2, size_t n);
+
+#include <string>
+#include <cassert>
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ char8_t s1[] = {1, 2, 3};
+ assert(std::char_traits<char8_t>::move(s1, s1+1, 2) == s1);
+ assert(s1[0] == char8_t(2));
+ assert(s1[1] == char8_t(3));
+ assert(s1[2] == char8_t(3));
+ s1[2] = char8_t(0);
+ assert(std::char_traits<char8_t>::move(s1+1, s1, 2) == s1+1);
+ assert(s1[0] == char8_t(2));
+ assert(s1[1] == char8_t(2));
+ assert(s1[2] == char8_t(3));
+ assert(std::char_traits<char8_t>::move(NULL, s1, 0) == NULL);
+ assert(std::char_traits<char8_t>::move(s1, NULL, 0) == s1);
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp
new file mode 100644
index 000000000000..274d93f133de
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/not_eof.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr int_type not_eof(int_type c);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert(std::char_traits<char8_t>::not_eof(u8'a') == u8'a');
+ assert(std::char_traits<char8_t>::not_eof(u8'A') == u8'A');
+ assert(std::char_traits<char8_t>::not_eof(0) == 0);
+ assert(std::char_traits<char8_t>::not_eof(std::char_traits<char8_t>::eof()) !=
+ std::char_traits<char8_t>::eof());
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp
new file mode 100644
index 000000000000..96159209feea
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_char_type.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr char_type to_char_type(int_type c);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert(std::char_traits<char8_t>::to_char_type(u8'a') == u8'a');
+ assert(std::char_traits<char8_t>::to_char_type(u8'A') == u8'A');
+ assert(std::char_traits<char8_t>::to_char_type(0) == 0);
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp
new file mode 100644
index 000000000000..659be36adbf4
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/to_int_type.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// static constexpr int_type to_int_type(char_type c);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert(std::char_traits<char8_t>::to_int_type(u8'a') == u8'a');
+ assert(std::char_traits<char8_t>::to_int_type(u8'A') == u8'A');
+ assert(std::char_traits<char8_t>::to_int_type(0) == 0);
+#endif
+}
diff --git a/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp
new file mode 100644
index 000000000000..64c27ffd740e
--- /dev/null
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/types.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template<> struct char_traits<char8_t>
+
+// typedef char8_t char_type;
+// typedef unsigned int int_type;
+// typedef streamoff off_type;
+// typedef u16streampos pos_type;
+// typedef mbstate_t state_type;
+
+#include <string>
+#include <type_traits>
+#include <cstdint>
+
+int main()
+{
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert((std::is_same<std::char_traits<char8_t>::char_type, char8_t>::value), "");
+ static_assert((std::is_same<std::char_traits<char8_t>::int_type, unsigned int>::value), "");
+ static_assert((std::is_same<std::char_traits<char8_t>::off_type, std::streamoff>::value), "");
+ static_assert((std::is_same<std::char_traits<char8_t>::pos_type, std::u16streampos>::value), "");
+ static_assert((std::is_same<std::char_traits<char8_t>::state_type, std::mbstate_t>::value), "");
+#endif
+}
diff --git a/test/std/strings/string.classes/typedefs.pass.cpp b/test/std/strings/string.classes/typedefs.pass.cpp
index 3aba1c3f15dd..15d97123519d 100644
--- a/test/std/strings/string.classes/typedefs.pass.cpp
+++ b/test/std/strings/string.classes/typedefs.pass.cpp
@@ -12,18 +12,24 @@
// Test for the existence of:
// basic_string typedef names
-// typedef basic_string<char> string;
+// typedef basic_string<char> string;
// typedef basic_string<char16_t> u16string;
+// typedef basic_string<char8_t> u8string; // C++20
// typedef basic_string<char32_t> u32string;
-// typedef basic_string<wchar_t> wstring;
+// typedef basic_string<wchar_t> wstring;
#include <string>
#include <type_traits>
+#include "test_macros.h"
+
int main()
{
static_assert((std::is_same<std::string, std::basic_string<char> >::value), "");
static_assert((std::is_same<std::wstring, std::basic_string<wchar_t> >::value), "");
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert((std::is_same<std::u8string, std::basic_string<char8_t> >::value), "");
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
static_assert((std::is_same<std::u16string, std::basic_string<char16_t> >::value), "");
static_assert((std::is_same<std::u32string, std::basic_string<char32_t> >::value), "");
diff --git a/test/std/strings/string.conversions/stod.pass.cpp b/test/std/strings/string.conversions/stod.pass.cpp
index 3d5db63e0983..8773a61840ed 100644
--- a/test/std/strings/string.conversions/stod.pass.cpp
+++ b/test/std/strings/string.conversions/stod.pass.cpp
@@ -15,6 +15,7 @@
#include <string>
#include <cmath>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stof.pass.cpp b/test/std/strings/string.conversions/stof.pass.cpp
index a5e587236e27..7c193648799d 100644
--- a/test/std/strings/string.conversions/stof.pass.cpp
+++ b/test/std/strings/string.conversions/stof.pass.cpp
@@ -19,6 +19,7 @@
#include <string>
#include <cmath>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stoi.pass.cpp b/test/std/strings/string.conversions/stoi.pass.cpp
index 8852d47f0011..efc43b3aa610 100644
--- a/test/std/strings/string.conversions/stoi.pass.cpp
+++ b/test/std/strings/string.conversions/stoi.pass.cpp
@@ -14,6 +14,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stol.pass.cpp b/test/std/strings/string.conversions/stol.pass.cpp
index 5e16735dcc8f..4815436222a7 100644
--- a/test/std/strings/string.conversions/stol.pass.cpp
+++ b/test/std/strings/string.conversions/stol.pass.cpp
@@ -18,6 +18,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stoll.pass.cpp b/test/std/strings/string.conversions/stoll.pass.cpp
index c33f9ee5e86f..fe4c40b78132 100644
--- a/test/std/strings/string.conversions/stoll.pass.cpp
+++ b/test/std/strings/string.conversions/stoll.pass.cpp
@@ -18,6 +18,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stoul.pass.cpp b/test/std/strings/string.conversions/stoul.pass.cpp
index 523c49a29de4..c79c949413db 100644
--- a/test/std/strings/string.conversions/stoul.pass.cpp
+++ b/test/std/strings/string.conversions/stoul.pass.cpp
@@ -18,6 +18,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/stoull.pass.cpp b/test/std/strings/string.conversions/stoull.pass.cpp
index 549c8da9a358..2ac883ec0936 100644
--- a/test/std/strings/string.conversions/stoull.pass.cpp
+++ b/test/std/strings/string.conversions/stoull.pass.cpp
@@ -18,6 +18,7 @@
#include <string>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.conversions/to_string.pass.cpp b/test/std/strings/string.conversions/to_string.pass.cpp
index 05e5e4b922a5..fdc682ce1031 100644
--- a/test/std/strings/string.conversions/to_string.pass.cpp
+++ b/test/std/strings/string.conversions/to_string.pass.cpp
@@ -19,6 +19,7 @@
// string to_string(double val);
// string to_string(long double val);
+#include <limits>
#include <string>
#include <cassert>
#include <sstream>
diff --git a/test/std/strings/string.conversions/to_wstring.pass.cpp b/test/std/strings/string.conversions/to_wstring.pass.cpp
index 281aa1a5e79b..2208ec5a3124 100644
--- a/test/std/strings/string.conversions/to_wstring.pass.cpp
+++ b/test/std/strings/string.conversions/to_wstring.pass.cpp
@@ -19,6 +19,7 @@
// wstring to_wstring(double val);
// wstring to_wstring(long double val);
+#include <limits>
#include <string>
#include <cassert>
#include <sstream>
diff --git a/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp b/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
index b21ba0422fdb..fda67c3bfa77 100644
--- a/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
+++ b/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
@@ -64,15 +64,13 @@ void test2 ( const CharT *s, size_t len ) {
}
int main () {
- typedef std::string_view string_view;
- typedef std::u16string_view u16string_view;
- typedef std::u32string_view u32string_view;
- typedef std::wstring_view wstring_view;
-
- test1<string_view> ();
- test1<u16string_view> ();
- test1<u32string_view> ();
- test1<wstring_view> ();
+ test1<std::string_view> ();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test1<std::u8string_view> ();
+#endif
+ test1<std::u16string_view> ();
+ test1<std::u32string_view> ();
+ test1<std::wstring_view> ();
test2 ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
test2 ( "ABCDE", 5 );
@@ -84,6 +82,13 @@ int main () {
test2 ( L"a", 1 );
test2 ( L"", 0 );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test2 ( u8"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
+ test2 ( u8"ABCDE", 5 );
+ test2 ( u8"a", 1 );
+ test2 ( u8"", 0 );
+#endif
+
#if TEST_STD_VER >= 11
test2 ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
test2 ( u"ABCDE", 5 );
diff --git a/test/std/strings/string.view/string.view.cons/assign.pass.cpp b/test/std/strings/string.view/string.view.cons/assign.pass.cpp
index 3307aa61d99f..bab788921b46 100644
--- a/test/std/strings/string.view/string.view.cons/assign.pass.cpp
+++ b/test/std/strings/string.view/string.view.cons/assign.pass.cpp
@@ -32,21 +32,27 @@ bool test (T sv0)
int main () {
- assert( test<std::string_view> ( "1234"));
+ assert( test<std::string_view> ( "1234"));
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ assert( test<std::u8string_view> (u8"1234"));
+#endif
#if TEST_STD_VER >= 11
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
- assert( test<std::u16string_view> (u"1234"));
- assert( test<std::u32string_view> (U"1234"));
+ assert( test<std::u16string_view> ( u"1234"));
+ assert( test<std::u32string_view> ( U"1234"));
#endif
#endif
- assert( test<std::wstring_view> (L"1234"));
+ assert( test<std::wstring_view> ( L"1234"));
#if TEST_STD_VER > 11
- static_assert( test<std::string_view> ({ "abc", 3}), "");
+ static_assert( test<std::string_view> ({ "abc", 3}), "");
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert( test<std::u8string_view> ({u8"abc", 3}), "");
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
- static_assert( test<std::u16string_view> ({u"abc", 3}), "");
- static_assert( test<std::u32string_view> ({U"abc", 3}), "");
+ static_assert( test<std::u16string_view> ({ u"abc", 3}), "");
+ static_assert( test<std::u32string_view> ({ U"abc", 3}), "");
#endif
- static_assert( test<std::wstring_view> ({L"abc", 3}), "");
+ static_assert( test<std::wstring_view> ({ L"abc", 3}), "");
#endif
}
diff --git a/test/std/strings/string.view/string.view.cons/default.pass.cpp b/test/std/strings/string.view/string.view.cons/default.pass.cpp
index 79fadf619f25..0c94918b53d4 100644
--- a/test/std/strings/string.view/string.view.cons/default.pass.cpp
+++ b/test/std/strings/string.view/string.view.cons/default.pass.cpp
@@ -37,14 +37,12 @@ void test () {
}
int main () {
- typedef std::string_view string_view;
- typedef std::u16string_view u16string_view;
- typedef std::u32string_view u32string_view;
- typedef std::wstring_view wstring_view;
-
- test<string_view> ();
- test<u16string_view> ();
- test<u32string_view> ();
- test<wstring_view> ();
+ test<std::string_view> ();
+ test<std::u16string_view> ();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test<std::u8string_view> ();
+#endif
+ test<std::u32string_view> ();
+ test<std::wstring_view> ();
}
diff --git a/test/std/strings/string.view/string.view.cons/from_string.pass.cpp b/test/std/strings/string.view/string.view.cons/from_string.pass.cpp
index 5fad2bfaab14..237d1221dbae 100644
--- a/test/std/strings/string.view/string.view.cons/from_string.pass.cpp
+++ b/test/std/strings/string.view/string.view.cons/from_string.pass.cpp
@@ -42,6 +42,12 @@ int main () {
test ( std::wstring(L"") );
test ( std::wstring() );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test ( std::u8string{u8"QBCDE"} );
+ test ( std::u8string{u8""} );
+ test ( std::u8string{} );
+#endif
+
#if TEST_STD_VER >= 11
test ( std::u16string{u"QBCDE"} );
test ( std::u16string{u""} );
diff --git a/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
index 2e9ebcb4c037..70515bf4847c 100644
--- a/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
+++ b/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
@@ -23,6 +23,9 @@ int main() {
{
test_hash_enabled_for_type<std::string_view>();
test_hash_enabled_for_type<std::wstring_view>();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test_hash_enabled_for_type<std::u8string_view>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test_hash_enabled_for_type<std::u16string_view>();
test_hash_enabled_for_type<std::u32string_view>();
diff --git a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
index 53c3d261d882..042e1dfabd30 100644
--- a/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
+++ b/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
@@ -59,6 +59,9 @@ test()
int main()
{
test<std::string_view>();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test<std::u8string_view>();
+#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<std::u16string_view>();
test<std::u32string_view>();
diff --git a/test/std/strings/string.view/string.view.iterators/begin.pass.cpp b/test/std/strings/string.view/string.view.iterators/begin.pass.cpp
index b766c51682fa..339f1f8fddbe 100644
--- a/test/std/strings/string.view/string.view.iterators/begin.pass.cpp
+++ b/test/std/strings/string.view/string.view.iterators/begin.pass.cpp
@@ -43,6 +43,9 @@ test(S s)
int main()
{
typedef std::string_view string_view;
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string_view u8string_view;
+#endif
typedef std::u16string_view u16string_view;
typedef std::u32string_view u32string_view;
typedef std::wstring_view wstring_view;
@@ -53,6 +56,9 @@ int main()
test(wstring_view ());
test(string_view ( "123"));
test(wstring_view (L"123"));
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test(u8string_view{u8"123"});
+#endif
#if TEST_STD_VER >= 11
test(u16string_view{u"123"});
test(u32string_view{U"123"});
@@ -61,16 +67,25 @@ int main()
#if TEST_STD_VER > 11
{
constexpr string_view sv { "123", 3 };
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ constexpr u8string_view u8sv {u8"123", 3 };
+#endif
constexpr u16string_view u16sv {u"123", 3 };
constexpr u32string_view u32sv {U"123", 3 };
constexpr wstring_view wsv {L"123", 3 };
static_assert ( *sv.begin() == sv[0], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *u8sv.begin() == u8sv[0], "" );
+#endif
static_assert ( *u16sv.begin() == u16sv[0], "" );
static_assert ( *u32sv.begin() == u32sv[0], "" );
static_assert ( *wsv.begin() == wsv[0], "" );
static_assert ( *sv.cbegin() == sv[0], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *u8sv.cbegin() == u8sv[0], "" );
+#endif
static_assert ( *u16sv.cbegin() == u16sv[0], "" );
static_assert ( *u32sv.cbegin() == u32sv[0], "" );
static_assert ( *wsv.cbegin() == wsv[0], "" );
diff --git a/test/std/strings/string.view/string.view.iterators/end.pass.cpp b/test/std/strings/string.view/string.view.iterators/end.pass.cpp
index b5759d701612..1533b49ba066 100644
--- a/test/std/strings/string.view/string.view.iterators/end.pass.cpp
+++ b/test/std/strings/string.view/string.view.iterators/end.pass.cpp
@@ -52,6 +52,9 @@ test(S s)
int main()
{
typedef std::string_view string_view;
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string_view u8string_view;
+#endif
typedef std::u16string_view u16string_view;
typedef std::u32string_view u32string_view;
typedef std::wstring_view wstring_view;
@@ -62,6 +65,9 @@ int main()
test(wstring_view ());
test(string_view ( "123"));
test(wstring_view (L"123"));
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test(u8string_view{u8"123"});
+#endif
#if TEST_STD_VER >= 11
test(u16string_view{u"123"});
test(u32string_view{U"123"});
@@ -70,16 +76,25 @@ int main()
#if TEST_STD_VER > 11
{
constexpr string_view sv { "123", 3 };
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ constexpr u8string_view u8sv {u8"123", 3 };
+#endif
constexpr u16string_view u16sv {u"123", 3 };
constexpr u32string_view u32sv {U"123", 3 };
constexpr wstring_view wsv {L"123", 3 };
static_assert ( sv.begin() != sv.end(), "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( u8sv.begin() != u8sv.end(), "" );
+#endif
static_assert ( u16sv.begin() != u16sv.end(), "" );
static_assert ( u32sv.begin() != u32sv.end(), "" );
static_assert ( wsv.begin() != wsv.end(), "" );
static_assert ( sv.begin() != sv.cend(), "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( u8sv.begin() != u8sv.cend(), "" );
+#endif
static_assert ( u16sv.begin() != u16sv.cend(), "" );
static_assert ( u32sv.begin() != u32sv.cend(), "" );
static_assert ( wsv.begin() != wsv.cend(), "" );
diff --git a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp
index 16a4da882739..0ec83871860f 100644
--- a/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp
+++ b/test/std/strings/string.view/string.view.iterators/rbegin.pass.cpp
@@ -44,6 +44,9 @@ test(S s)
int main()
{
typedef std::string_view string_view;
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string_view u8string_view;
+#endif
typedef std::u16string_view u16string_view;
typedef std::u32string_view u32string_view;
typedef std::wstring_view wstring_view;
@@ -54,6 +57,9 @@ int main()
test(wstring_view ());
test(string_view ( "123"));
test(wstring_view (L"123"));
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test(u8string_view{u8"123"});
+#endif
#if TEST_STD_VER >= 11
test(u16string_view{u"123"});
test(u32string_view{U"123"});
@@ -62,16 +68,25 @@ int main()
#if TEST_STD_VER > 14
{
constexpr string_view sv { "123", 3 };
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ constexpr u8string_view u8sv {u8"123", 3 };
+#endif
constexpr u16string_view u16sv {u"123", 3 };
constexpr u32string_view u32sv {U"123", 3 };
constexpr wstring_view wsv {L"123", 3 };
static_assert ( *sv.rbegin() == sv[2], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *u8sv.rbegin() == u8sv[2], "" );
+#endif
static_assert ( *u16sv.rbegin() == u16sv[2], "" );
static_assert ( *u32sv.rbegin() == u32sv[2], "" );
static_assert ( *wsv.rbegin() == wsv[2], "" );
static_assert ( *sv.crbegin() == sv[2], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *u8sv.crbegin() == u8sv[2], "" );
+#endif
static_assert ( *u16sv.crbegin() == u16sv[2], "" );
static_assert ( *u32sv.crbegin() == u32sv[2], "" );
static_assert ( *wsv.crbegin() == wsv[2], "" );
diff --git a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp
index 08f9e5a7755b..dfcb836f16a8 100644
--- a/test/std/strings/string.view/string.view.iterators/rend.pass.cpp
+++ b/test/std/strings/string.view/string.view.iterators/rend.pass.cpp
@@ -52,6 +52,9 @@ test(S s)
int main()
{
typedef std::string_view string_view;
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string_view u8string_view;
+#endif
typedef std::u16string_view u16string_view;
typedef std::u32string_view u32string_view;
typedef std::wstring_view wstring_view;
@@ -62,6 +65,9 @@ int main()
test(wstring_view ());
test(string_view ( "123"));
test(wstring_view (L"123"));
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test(u8string_view{u8"123"});
+#endif
#if TEST_STD_VER >= 11
test(u16string_view{u"123"});
test(u32string_view{U"123"});
@@ -70,16 +76,25 @@ int main()
#if TEST_STD_VER > 14
{
constexpr string_view sv { "123", 3 };
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ constexpr u8string_view u8sv {u8"123", 3 };
+#endif
constexpr u16string_view u16sv {u"123", 3 };
constexpr u32string_view u32sv {U"123", 3 };
constexpr wstring_view wsv {L"123", 3 };
static_assert ( *--sv.rend() == sv[0], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *--u8sv.rend() == u8sv[0], "" );
+#endif
static_assert ( *--u16sv.rend() == u16sv[0], "" );
static_assert ( *--u32sv.rend() == u32sv[0], "" );
static_assert ( *--wsv.rend() == wsv[0], "" );
static_assert ( *--sv.crend() == sv[0], "" );
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ static_assert ( *--u8sv.crend() == u8sv[0], "" );
+#endif
static_assert ( *--u16sv.crend() == u16sv[0], "" );
static_assert ( *--u32sv.crend() == u32sv[0], "" );
static_assert ( *--wsv.crend() == wsv[0], "" );
diff --git a/test/std/strings/string.view/string.view.ops/compare.pointer_size.pass.cpp b/test/std/strings/string.view/string.view.ops/compare.pointer_size.pass.cpp
index 84f9ce080443..546590326c4b 100644
--- a/test/std/strings/string.view/string.view.ops/compare.pointer_size.pass.cpp
+++ b/test/std/strings/string.view/string.view.ops/compare.pointer_size.pass.cpp
@@ -13,6 +13,7 @@
#include <string_view>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
#include "constexpr_char_traits.hpp"
diff --git a/test/std/strings/string.view/string.view.ops/compare.size_size_sv.pass.cpp b/test/std/strings/string.view/string.view.ops/compare.size_size_sv.pass.cpp
index 2bef7fdbac1a..d170949c77ec 100644
--- a/test/std/strings/string.view/string.view.ops/compare.size_size_sv.pass.cpp
+++ b/test/std/strings/string.view/string.view.ops/compare.size_size_sv.pass.cpp
@@ -13,6 +13,7 @@
#include <string_view>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
#include "constexpr_char_traits.hpp"
diff --git a/test/std/strings/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp b/test/std/strings/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp
index 8256c997b118..f1489e7df48b 100644
--- a/test/std/strings/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp
+++ b/test/std/strings/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp
@@ -14,6 +14,7 @@
#include <string_view>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
#include "constexpr_char_traits.hpp"
diff --git a/test/std/strings/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp b/test/std/strings/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp
index 5b47486192cd..e93d6ddfea30 100644
--- a/test/std/strings/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp
+++ b/test/std/strings/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp
@@ -14,6 +14,7 @@
#include <string_view>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
#include "constexpr_char_traits.hpp"
diff --git a/test/std/strings/string.view/string.view.ops/copy.pass.cpp b/test/std/strings/string.view/string.view.ops/copy.pass.cpp
index 41601467b812..98e83ef5053b 100644
--- a/test/std/strings/string.view/string.view.ops/copy.pass.cpp
+++ b/test/std/strings/string.view/string.view.ops/copy.pass.cpp
@@ -21,6 +21,7 @@
#include <string_view>
#include <algorithm>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/strings/string.view/string_view.literals/literal.pass.cpp b/test/std/strings/string.view/string_view.literals/literal.pass.cpp
index 79fe355289d1..cc2202e8397b 100644
--- a/test/std/strings/string.view/string_view.literals/literal.pass.cpp
+++ b/test/std/strings/string.view/string_view.literals/literal.pass.cpp
@@ -16,38 +16,48 @@
#include <string_view>
#include <cassert>
+#include "test_macros.h"
+
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ typedef std::u8string_view u8string_view;
+#else
+ typedef std::string_view u8string_view;
+#endif
+
int main()
{
using namespace std::literals::string_view_literals;
static_assert ( std::is_same<decltype( "Hi"sv), std::string_view>::value, "" );
- static_assert ( std::is_same<decltype( u8"Hi"sv), std::string_view>::value, "" );
+ static_assert ( std::is_same<decltype( u8"Hi"sv), u8string_view>::value, "" );
static_assert ( std::is_same<decltype( L"Hi"sv), std::wstring_view>::value, "" );
static_assert ( std::is_same<decltype( u"Hi"sv), std::u16string_view>::value, "" );
static_assert ( std::is_same<decltype( U"Hi"sv), std::u32string_view>::value, "" );
std::string_view foo;
std::wstring_view Lfoo;
+ u8string_view u8foo;
std::u16string_view ufoo;
std::u32string_view Ufoo;
- foo = ""sv; assert( foo.size() == 0);
- foo = u8""sv; assert( foo.size() == 0);
- Lfoo = L""sv; assert(Lfoo.size() == 0);
- ufoo = u""sv; assert(ufoo.size() == 0);
- Ufoo = U""sv; assert(Ufoo.size() == 0);
-
- foo = " "sv; assert( foo.size() == 1);
- foo = u8" "sv; assert( foo.size() == 1);
- Lfoo = L" "sv; assert(Lfoo.size() == 1);
- ufoo = u" "sv; assert(ufoo.size() == 1);
- Ufoo = U" "sv; assert(Ufoo.size() == 1);
-
- foo = "ABC"sv; assert( foo == "ABC"); assert( foo == std::string_view ( "ABC"));
- foo = u8"ABC"sv; assert( foo == u8"ABC"); assert( foo == std::string_view (u8"ABC"));
- Lfoo = L"ABC"sv; assert(Lfoo == L"ABC"); assert(Lfoo == std::wstring_view ( L"ABC"));
- ufoo = u"ABC"sv; assert(ufoo == u"ABC"); assert(ufoo == std::u16string_view( u"ABC"));
- Ufoo = U"ABC"sv; assert(Ufoo == U"ABC"); assert(Ufoo == std::u32string_view( U"ABC"));
+
+ foo = ""sv; assert( foo.size() == 0);
+ u8foo = u8""sv; assert(u8foo.size() == 0);
+ Lfoo = L""sv; assert( Lfoo.size() == 0);
+ ufoo = u""sv; assert( ufoo.size() == 0);
+ Ufoo = U""sv; assert( Ufoo.size() == 0);
+
+ foo = " "sv; assert( foo.size() == 1);
+ u8foo = u8" "sv; assert(u8foo.size() == 1);
+ Lfoo = L" "sv; assert( Lfoo.size() == 1);
+ ufoo = u" "sv; assert( ufoo.size() == 1);
+ Ufoo = U" "sv; assert( Ufoo.size() == 1);
+
+ foo = "ABC"sv; assert( foo == "ABC"); assert( foo == std::string_view ( "ABC"));
+ u8foo = u8"ABC"sv; assert(u8foo == u8"ABC"); assert(u8foo == u8string_view (u8"ABC"));
+ Lfoo = L"ABC"sv; assert( Lfoo == L"ABC"); assert( Lfoo == std::wstring_view ( L"ABC"));
+ ufoo = u"ABC"sv; assert( ufoo == u"ABC"); assert( ufoo == std::u16string_view( u"ABC"));
+ Ufoo = U"ABC"sv; assert( Ufoo == U"ABC"); assert( Ufoo == std::u32string_view( U"ABC"));
static_assert( "ABC"sv.size() == 3, "");
static_assert(u8"ABC"sv.size() == 3, "");
diff --git a/test/std/strings/string.view/types.pass.cpp b/test/std/strings/string.view/types.pass.cpp
index 4c29959f0951..2763f7fb47ca 100644
--- a/test/std/strings/string.view/types.pass.cpp
+++ b/test/std/strings/string.view/types.pass.cpp
@@ -72,6 +72,9 @@ int main()
{
test<std::char_traits<char> >();
test<std::char_traits<wchar_t> >();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test<std::char_traits<char8_t> >();
+#endif
static_assert((std::is_same<std::basic_string_view<char>::traits_type,
std::char_traits<char> >::value), "");
}
diff --git a/test/std/strings/strings.erasure/erase.pass.cpp b/test/std/strings/strings.erasure/erase.pass.cpp
new file mode 100644
index 000000000000..657a56c73156
--- /dev/null
+++ b/test/std/strings/strings.erasure/erase.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template <class charT, class traits, class Allocator, class U>
+// void erase(basic_string<charT, traits, Allocator>& c, const U& value);
+
+
+#include <string>
+#include <optional>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class U>
+void
+test0(S s, U val, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase(s, val)));
+ std::erase(s, val);
+ LIBCPP_ASSERT(s.__invariants());
+ assert(s == expected);
+}
+
+template <class S>
+void test()
+{
+
+ test0(S(""), 'a', S(""));
+
+ test0(S("a"), 'a', S(""));
+ test0(S("a"), 'b', S("a"));
+
+ test0(S("ab"), 'a', S("b"));
+ test0(S("ab"), 'b', S("a"));
+ test0(S("ab"), 'c', S("ab"));
+ test0(S("aa"), 'a', S(""));
+ test0(S("aa"), 'c', S("aa"));
+
+ test0(S("abc"), 'a', S("bc"));
+ test0(S("abc"), 'b', S("ac"));
+ test0(S("abc"), 'c', S("ab"));
+ test0(S("abc"), 'd', S("abc"));
+
+ test0(S("aab"), 'a', S("b"));
+ test0(S("aab"), 'b', S("aa"));
+ test0(S("aab"), 'c', S("aab"));
+ test0(S("abb"), 'a', S("bb"));
+ test0(S("abb"), 'b', S("a"));
+ test0(S("abb"), 'c', S("abb"));
+ test0(S("aaa"), 'a', S(""));
+ test0(S("aaa"), 'b', S("aaa"));
+
+// Test cross-type erasure
+ using opt = std::optional<typename S::value_type>;
+ test0(S("aba"), opt(), S("aba"));
+ test0(S("aba"), opt('a'), S("b"));
+ test0(S("aba"), opt('b'), S("aa"));
+ test0(S("aba"), opt('c'), S("aba"));
+}
+
+int main()
+{
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> ();
+ test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> ();
+}
diff --git a/test/std/strings/strings.erasure/erase_if.pass.cpp b/test/std/strings/strings.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000000..d7014868fd35
--- /dev/null
+++ b/test/std/strings/strings.erasure/erase_if.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <string>
+
+// template <class charT, class traits, class Allocator, class Predicate>
+// void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);
+
+#include <string>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S, class Pred>
+void
+test0(S s, Pred p, S expected)
+{
+ ASSERT_SAME_TYPE(void, decltype(std::erase_if(s, p)));
+ std::erase_if(s, p);
+ LIBCPP_ASSERT(s.__invariants());
+ assert(s == expected);
+}
+
+template <typename S>
+void test()
+{
+ auto isA = [](auto ch) { return ch == 'a';};
+ auto isB = [](auto ch) { return ch == 'b';};
+ auto isC = [](auto ch) { return ch == 'c';};
+ auto isD = [](auto ch) { return ch == 'd';};
+ auto True = [](auto) { return true; };
+ auto False = [](auto) { return false; };
+
+ test0(S(""), isA, S(""));
+
+ test0(S("a"), isA, S(""));
+ test0(S("a"), isB, S("a"));
+
+ test0(S("ab"), isA, S("b"));
+ test0(S("ab"), isB, S("a"));
+ test0(S("ab"), isC, S("ab"));
+ test0(S("aa"), isA, S(""));
+ test0(S("aa"), isC, S("aa"));
+
+ test0(S("abc"), isA, S("bc"));
+ test0(S("abc"), isB, S("ac"));
+ test0(S("abc"), isC, S("ab"));
+ test0(S("abc"), isD, S("abc"));
+
+ test0(S("aab"), isA, S("b"));
+ test0(S("aab"), isB, S("aa"));
+ test0(S("aab"), isC, S("aab"));
+ test0(S("abb"), isA, S("bb"));
+ test0(S("abb"), isB, S("a"));
+ test0(S("abb"), isC, S("abb"));
+ test0(S("aaa"), isA, S(""));
+ test0(S("aaa"), isB, S("aaa"));
+
+ test0(S("aba"), False, S("aba"));
+ test0(S("aba"), True, S(""));
+}
+
+int main()
+{
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>> ();
+ test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>> ();
+}
diff --git a/test/std/thread/futures/futures.async/async_race.38682.pass.cpp b/test/std/thread/futures/futures.async/async_race.38682.pass.cpp
new file mode 100644
index 000000000000..bc82ba849c3b
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async_race.38682.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
+
+// There's currently no release of OS X whose dylib contains the patch for
+// PR38682. Since the fix for future<void> is in the dylib, this test may fail.
+// UNSUPPORTED: with_system_cxx_lib=macosx10.14
+// UNSUPPORTED: with_system_cxx_lib=macosx10.13
+// UNSUPPORTED: with_system_cxx_lib=macosx10.12
+// UNSUPPORTED: with_system_cxx_lib=macosx10.11
+// UNSUPPORTED: with_system_cxx_lib=macosx10.10
+// UNSUPPORTED: with_system_cxx_lib=macosx10.9
+// UNSUPPORTED: with_system_cxx_lib=macosx10.8
+// UNSUPPORTED: with_system_cxx_lib=macosx10.7
+
+// This test is designed to cause and allow TSAN to detect a race condition
+// in std::async, as reported in https://bugs.llvm.org/show_bug.cgi?id=38682.
+
+#include <cassert>
+#include <functional>
+#include <future>
+#include <numeric>
+#include <vector>
+
+
+static int worker(std::vector<int> const& data) {
+ return std::accumulate(data.begin(), data.end(), 0);
+}
+
+static int& worker_ref(int& i) { return i; }
+
+static void worker_void() { }
+
+int main() {
+ // future<T>
+ {
+ std::vector<int> const v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ for (int i = 0; i != 20; ++i) {
+ std::future<int> fut = std::async(std::launch::async, worker, v);
+ int answer = fut.get();
+ assert(answer == 55);
+ }
+ }
+
+ // future<T&>
+ {
+ for (int i = 0; i != 20; ++i) {
+ std::future<int&> fut = std::async(std::launch::async, worker_ref, std::ref(i));
+ int& answer = fut.get();
+ assert(answer == i);
+ }
+ }
+
+ // future<void>
+ {
+ for (int i = 0; i != 20; ++i) {
+ std::future<void> fut = std::async(std::launch::async, worker_void);
+ fut.get();
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
index 0ddbd0b08936..4e107ca9abfb 100644
--- a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
+++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -10,6 +10,8 @@
// UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03
+// FLAKY_TEST.
+
// <future>
// class shared_future<R>
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
index ca48eee19d27..8aa233f66b5a 100644
--- a/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <condition_variable>
// class condition_variable;
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
index 98f6c432c977..16e6ff9f105b 100644
--- a/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <condition_variable>
// class condition_variable_any;
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
index 83271009a67e..79c639eb6cad 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <mutex>
// template <class Mutex> class lock_guard;
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
index 97f9d07c1512..4a2db39e87a9 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <mutex>
// template <class Mutex> class lock_guard;
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
index 7f89f0af801f..694e311b7bfb 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
@@ -10,6 +10,8 @@
// UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03, c++11
+// FLAKY_TEST
+
// <shared_mutex>
// template <class Mutex> class shared_lock;
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
index dcfdfd11a7e1..f63256373b27 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <mutex>
// template <class Mutex> class unique_lock;
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
index cb5c55925eef..ebaf3e6deb23 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
@@ -9,6 +9,8 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST
+
// <mutex>
// template <class Mutex> class unique_lock;
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
index d419b8cc855c..be3fc9c5d1eb 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -157,8 +157,11 @@ int main()
{
assert(G::n_alive == 0);
assert(!G::op_run);
- std::thread t((G()));
- t.join();
+ {
+ G g;
+ std::thread t(g);
+ t.join();
+ }
assert(G::n_alive == 0);
assert(G::op_run);
}
@@ -185,8 +188,11 @@ int main()
{
assert(G::n_alive == 0);
assert(!G::op_run);
- std::thread t(G(), 5, 5.5);
- t.join();
+ {
+ G g;
+ std::thread t(g, 5, 5.5);
+ t.join();
+ }
assert(G::n_alive == 0);
assert(G::op_run);
}
diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
index 6b622029365c..0a5a3e419d56 100644
--- a/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// FLAKY_TEST.
// <thread>
diff --git a/test/std/utilities/any/any.class/any.assign/copy.pass.cpp b/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
index 68de5e3d1368..c148a39de83c 100644
--- a/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
+++ b/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.7
+// XFAIL: availability=macosx10.8
// <any>
diff --git a/test/std/utilities/any/any.class/any.assign/move.pass.cpp b/test/std/utilities/any/any.class/any.assign/move.pass.cpp
index 418f200beb7a..19289cc3968f 100644
--- a/test/std/utilities/any/any.class/any.assign/move.pass.cpp
+++ b/test/std/utilities/any/any.class/any.assign/move.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.assign/value.pass.cpp b/test/std/utilities/any/any.class/any.assign/value.pass.cpp
index ddedb886cc04..d2e2266046c1 100644
--- a/test/std/utilities/any/any.class/any.assign/value.pass.cpp
+++ b/test/std/utilities/any/any.class/any.assign/value.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
@@ -125,7 +126,7 @@ template <class Tp, bool Move = false>
void test_assign_throws() {
#if !defined(TEST_HAS_NO_EXCEPTIONS)
auto try_throw =
- [](any& lhs, auto&& rhs) {
+ [](any& lhs, Tp& rhs) {
try {
Move ? lhs = std::move(rhs)
: lhs = rhs;
diff --git a/test/std/utilities/any/any.class/any.cons/copy.pass.cpp b/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
index aceb9e6cf3d5..79cac4236496 100644
--- a/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
+++ b/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp b/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
index d01a88da5dfc..589b3c46d13e 100644
--- a/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
+++ b/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.cons/move.pass.cpp b/test/std/utilities/any/any.class/any.cons/move.pass.cpp
index 09e9288e0ab3..1310b6b12298 100644
--- a/test/std/utilities/any/any.class/any.cons/move.pass.cpp
+++ b/test/std/utilities/any/any.class/any.cons/move.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.cons/value.pass.cpp b/test/std/utilities/any/any.class/any.cons/value.pass.cpp
index d18de0664c77..83c78923de5e 100644
--- a/test/std/utilities/any/any.class/any.cons/value.pass.cpp
+++ b/test/std/utilities/any/any.class/any.cons/value.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp b/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
index 789a861ee3d6..fdd3c8334677 100644
--- a/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
+++ b/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp b/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp
index 2e781d954e68..888e3a8703e7 100644
--- a/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp
+++ b/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp b/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
index f56a2565622f..9b5ab5f033e9 100644
--- a/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
+++ b/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
index a5fa93218c65..cc118b348480 100644
--- a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
index 419fd1a40cf8..85ee8fef3c8d 100644
--- a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp
index 9638521260a9..0e3b6a43f89c 100644
--- a/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp
@@ -22,6 +22,10 @@ struct TestType {};
using std::any;
using std::any_cast;
+// On platforms that do not support any_cast, an additional availability error
+// is triggered by these tests.
+// expected-error@any_cast_request_invalid_value_category.fail.cpp:* 0+ {{call to unavailable function 'any_cast': introduced in macOS 10.14}}
+
void test_const_lvalue_cast_request_non_const_lvalue()
{
const any a;
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp b/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp
index bad229dac886..cb924499061d 100644
--- a/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp
+++ b/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp
@@ -21,6 +21,10 @@
struct TestType {};
struct TestType2 {};
+// On platforms that do not support any_cast, an additional availability error
+// is triggered by these tests.
+// expected-error@const_correctness.fail.cpp:* 0+ {{call to unavailable function 'any_cast': introduced in macOS 10.14}}
+
int main()
{
using std::any;
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp b/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
index 2d18cf4ba090..e88deafce240 100644
--- a/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
+++ b/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
@@ -40,6 +40,10 @@ struct no_move {
no_move(no_move const&) {}
};
+// On platforms that do not support any_cast, an additional availability error
+// is triggered by these tests.
+// expected-error@not_copy_constructible.fail.cpp:* 0+ {{call to unavailable function 'any_cast': introduced in macOS 10.14}}
+
int main() {
any a;
// expected-error-re@any:* {{static_assert failed{{.*}} "ValueType is required to be an lvalue reference or a CopyConstructible type"}}
diff --git a/test/std/utilities/any/any.nonmembers/make_any.pass.cpp b/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
index 9850851fc6ed..dad2973fbcb2 100644
--- a/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
+++ b/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/any/any.nonmembers/swap.pass.cpp b/test/std/utilities/any/any.nonmembers/swap.pass.cpp
index c723b6e08149..a2a40d138a1d 100644
--- a/test/std/utilities/any/any.nonmembers/swap.pass.cpp
+++ b/test/std/utilities/any/any.nonmembers/swap.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <any>
diff --git a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
index 3fc533a772fa..7b08f3047f6c 100644
--- a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -8,6 +8,16 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11
+
+// XFAIL: with_system_cxx_lib=macosx10.14
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+// XFAIL: with_system_cxx_lib=macosx10.11
+// XFAIL: with_system_cxx_lib=macosx10.10
+// XFAIL: with_system_cxx_lib=macosx10.9
+// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
// <charconv>
// from_chars_result from_chars(const char* first, const char* last,
@@ -174,8 +184,7 @@ struct test_signed : roundtrip_test_base<T>
}
};
-int
-main()
+int main()
{
run<test_basics>(integrals);
run<test_signed>(all_signed);
diff --git a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
index 50ca5b1906ea..63891b1ee8a5 100644
--- a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
+++ b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
@@ -8,6 +8,16 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11
+
+// XFAIL: with_system_cxx_lib=macosx10.14
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+// XFAIL: with_system_cxx_lib=macosx10.11
+// XFAIL: with_system_cxx_lib=macosx10.10
+// XFAIL: with_system_cxx_lib=macosx10.9
+// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
// <charconv>
// to_chars_result to_chars(char* first, char* last, Integral value,
@@ -72,8 +82,7 @@ struct test_signed : to_chars_test_base<T>
}
};
-int
-main()
+int main()
{
run<test_basics>(integrals);
run<test_signed>(all_signed);
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
index 5b660da617a8..ac43dd769ed6 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
@@ -42,8 +42,7 @@ struct plus_one
}
};
-int
-main()
+int main()
{
using std::placeholders::_1;
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp
index faf4f11573d1..e9b399a2edd2 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp
@@ -12,7 +12,7 @@
// class function<R(ArgTypes...)>
// function(const function& f);
-// function(function&& f);
+// function(function&& f); // noexcept in C++20
#include <functional>
#include <memory>
@@ -109,6 +109,10 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>());
assert(f.target<int(*)(int)>() == 0);
+ LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#endif
std::function<int(int)> f2 = std::move(f);
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
@@ -129,6 +133,10 @@ int main()
assert(A::count == 1);
assert(f.target<A>() == nullptr);
assert(f.target<Ref>());
+ LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#endif
std::function<int(int)> f2(std::move(f));
assert(A::count == 1);
assert(f2.target<A>() == nullptr);
@@ -144,6 +152,10 @@ int main()
std::function<int(int)> f(p);
assert(f.target<A>() == nullptr);
assert(f.target<Ptr>());
+ LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
+#endif
std::function<int(int)> f2(std::move(f));
assert(f2.target<A>() == nullptr);
assert(f2.target<Ptr>());
diff --git a/test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.fail.cpp b/test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.fail.cpp
new file mode 100644
index 000000000000..c8247a195917
--- /dev/null
+++ b/test/std/utilities/function.objects/negators/binary_negate.depr_in_cxx17.fail.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// binary_negate
+// deprecated in C++17
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Predicate {
+ typedef int first_argument_type;
+ typedef int second_argument_type;
+ bool operator()(first_argument_type, second_argument_type) const { return true; }
+};
+
+int main() {
+ std::binary_negate<Predicate> f((Predicate())); // expected-error{{'binary_negate<Predicate>' is deprecated}}
+ (void)f;
+}
diff --git a/test/std/utilities/function.objects/negators/not1.depr_in_cxx17.fail.cpp b/test/std/utilities/function.objects/negators/not1.depr_in_cxx17.fail.cpp
new file mode 100644
index 000000000000..584d3ab0639f
--- /dev/null
+++ b/test/std/utilities/function.objects/negators/not1.depr_in_cxx17.fail.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// not1
+// deprecated in C++17
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Predicate {
+ typedef int argument_type;
+ bool operator()(argument_type) const { return true; }
+};
+
+int main() {
+ std::not1(Predicate()); // expected-error{{'not1<Predicate>' is deprecated}}
+}
diff --git a/test/std/utilities/function.objects/negators/not2.depr_in_cxx17.fail.cpp b/test/std/utilities/function.objects/negators/not2.depr_in_cxx17.fail.cpp
new file mode 100644
index 000000000000..92e3be580aff
--- /dev/null
+++ b/test/std/utilities/function.objects/negators/not2.depr_in_cxx17.fail.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// not2
+// deprecated in C++17
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Predicate {
+ typedef int first_argument_type;
+ typedef int second_argument_type;
+ bool operator()(first_argument_type, second_argument_type) const { return true; }
+};
+
+int main() {
+ std::not2(Predicate()); // expected-error{{'not2<Predicate>' is deprecated}}
+}
diff --git a/test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.fail.cpp b/test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.fail.cpp
new file mode 100644
index 000000000000..b38a7d2f1c09
--- /dev/null
+++ b/test/std/utilities/function.objects/negators/unary_negate.depr_in_cxx17.fail.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// unary_negate
+// deprecated in C++17
+
+// UNSUPPORTED: clang-4.0
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// REQUIRES: verify-support
+
+// MODULES_DEFINES: _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_ENABLE_DEPRECATION_WARNINGS
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Predicate {
+ typedef int argument_type;
+ bool operator()(argument_type) const { return true; }
+};
+
+int main() {
+ std::unary_negate<Predicate> f((Predicate())); // expected-error{{'unary_negate<Predicate>' is deprecated}}
+ (void)f;
+}
diff --git a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
index 261a306ca156..27d498ec8282 100644
--- a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
+++ b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
@@ -11,11 +11,11 @@
// reference_wrapper
-// Test that reference wrapper meets the requirements of TriviallyCopyable,
-// CopyConstructible and CopyAssignable.
+// Test that reference wrapper meets the requirements of CopyConstructible and
+// CopyAssignable, and TriviallyCopyable (starting in C++14).
// Test fails due to use of is_trivially_* trait.
-// XFAIL: gcc-4.9
+// XFAIL: gcc-4.9 && c++14
#include <functional>
#include <type_traits>
@@ -48,8 +48,9 @@ void test()
typedef std::reference_wrapper<T> Wrap;
static_assert(std::is_copy_constructible<Wrap>::value, "");
static_assert(std::is_copy_assignable<Wrap>::value, "");
- // Extension up for standardization: See N4151.
+#if TEST_STD_VER >= 14
static_assert(std::is_trivially_copyable<Wrap>::value, "");
+#endif
}
int main()
diff --git a/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp b/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp
new file mode 100644
index 000000000000..a63dc5b15f4b
--- /dev/null
+++ b/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// template <class T>
+// struct unwrap_ref_decay;
+//
+// template <class T>
+// using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+#include <functional>
+#include <type_traits>
+
+
+template <typename T, typename Result>
+void check() {
+ static_assert(std::is_same_v<typename std::unwrap_ref_decay<T>::type, Result>);
+ static_assert(std::is_same_v<typename std::unwrap_ref_decay<T>::type, std::unwrap_ref_decay_t<T>>);
+}
+
+struct T { };
+
+int main() {
+ check<T, T>();
+ check<T&, T>();
+ check<T const, T>();
+ check<T const&, T>();
+ check<T*, T*>();
+ check<T const*, T const*>();
+ check<T[3], T*>();
+ check<T const [3], T const*>();
+ check<T (), T (*)()>();
+ check<T (int) const, T (int) const>();
+ check<T (int) &, T (int) &>();
+ check<T (int) &&, T (int) &&>();
+
+ check<std::reference_wrapper<T>, T&>();
+ check<std::reference_wrapper<T>&, T&>();
+ check<std::reference_wrapper<T const>, T const&>();
+ check<std::reference_wrapper<T const>&, T const&>();
+ check<std::reference_wrapper<T*>, T*&>();
+ check<std::reference_wrapper<T*>&, T*&>();
+ check<std::reference_wrapper<T const*>, T const*&>();
+ check<std::reference_wrapper<T const*>&, T const*&>();
+ check<std::reference_wrapper<T[3]>, T (&)[3]>();
+ check<std::reference_wrapper<T[3]>&, T (&)[3]>();
+ check<std::reference_wrapper<T ()>, T (&)()>();
+ check<std::reference_wrapper<T ()>&, T (&)()>();
+}
diff --git a/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp b/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp
new file mode 100644
index 000000000000..441ddf4bd568
--- /dev/null
+++ b/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+//
+// template <class T>
+// struct unwrap_reference;
+//
+// template <class T>
+// using unwrap_reference_t = typename unwrap_reference<T>::type;
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+#include <functional>
+#include <type_traits>
+
+
+template <typename T, typename Expected>
+void check_equal() {
+ static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, Expected>);
+ static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, std::unwrap_reference_t<T>>);
+}
+
+template <typename T>
+void check() {
+ check_equal<T, T>();
+ check_equal<T&, T&>();
+ check_equal<T const, T const>();
+ check_equal<T const&, T const&>();
+
+ check_equal<std::reference_wrapper<T>, T&>();
+ check_equal<std::reference_wrapper<T const>, T const&>();
+}
+
+struct T { };
+
+int main() {
+ check<T>();
+ check<int>();
+ check<float>();
+
+ check<T*>();
+ check<int*>();
+ check<float*>();
+}
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
index 1a812876bf0c..1060b73434d7 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp
@@ -73,7 +73,7 @@ int main()
std::aligned_storage<sizeof(VT)>::type store;
std::allocator_traits<Alloc>::destroy(a, (VT*)&store);
}
-#if TEST_STD_VER >= 11
+#if defined(_LIBCPP_VERSION) || TEST_STD_VER >= 11
{
A0::count = 0;
b_destroy = 0;
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp
index 12c0d02227fa..7a2d76c6d670 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp
@@ -16,6 +16,7 @@
// ...
// };
+#include <limits>
#include <memory>
#include <new>
#include <type_traits>
diff --git a/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
index 70c5e46965a0..b53175376dd5 100644
--- a/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
@@ -14,6 +14,7 @@
#include <memory>
#include <cassert>
+#include <cstddef> // for std::max_align_t
#include <iostream>
#include "test_macros.h"
diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
index a8ad936c9366..85b15ea5b12b 100644
--- a/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
+++ b/test/std/utilities/memory/pointer.traits/pointer.traits.functions/pointer_to.pass.cpp
@@ -39,6 +39,7 @@ int main()
{
{
int i = 0;
+ static_assert((std::is_same<A<int>, decltype(std::pointer_traits<A<int> >::pointer_to(i))>::value), "");
A<int> a = std::pointer_traits<A<int> >::pointer_to(i);
assert(a.t_ == &i);
}
diff --git a/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
index fc44d9d77a2f..756f89429693 100644
--- a/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
+++ b/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
@@ -12,21 +12,33 @@
// template <class T>
// struct pointer_traits<T*>
// {
-// static pointer pointer_to(<details>);
+// static pointer pointer_to(<details>); // constexpr in C++20
// ...
// };
#include <memory>
#include <cassert>
+#include "test_macros.h"
-int main()
-{
+#if TEST_STD_VER > 17
+constexpr
+#endif
+bool check() {
{
int i = 0;
+ static_assert((std::is_same<int *, decltype(std::pointer_traits<int*>::pointer_to(i))>::value), "");
int* a = std::pointer_traits<int*>::pointer_to(i);
assert(a == &i);
}
{
(std::pointer_traits<void*>::element_type)0;
}
+ return true;
+}
+
+int main() {
+ check();
+#if TEST_STD_VER > 17
+ static_assert(check(), "");
+#endif
}
diff --git a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp
index 62a3be80d8b6..eb66ed4ad47b 100644
--- a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp
+++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp
@@ -15,6 +15,13 @@
#include "test_macros.h"
+#if TEST_STD_VER >= 11
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
+
int A_constructed = 0;
struct A
@@ -27,6 +34,7 @@ public:
~A() {--A_constructed; data_ = 0;}
bool operator==(int i) const {return data_ == i;}
+ A* operator& () DELETE_FUNCTION;
};
int main()
diff --git a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
index 3df8dd0eded0..4d9d698f7420 100644
--- a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
+++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
@@ -16,6 +16,12 @@
#include "test_macros.h"
#include <MoveOnly.h>
+#if TEST_STD_VER >= 11
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
int A_constructed = 0;
struct A
@@ -28,6 +34,7 @@ public:
~A() {--A_constructed; data_ = 0;}
bool operator==(int i) const {return data_ == i;}
+ A* operator& () DELETE_FUNCTION;
};
int main()
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
index 3e4a99e981d4..a430b5d796e2 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
@@ -23,6 +23,12 @@
#include "test_allocator.h"
#include "min_allocator.h"
+#if TEST_STD_VER >= 11
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
int new_count = 0;
struct A
@@ -37,6 +43,8 @@ struct A
int get_int() const {return int_;}
char get_char() const {return char_;}
+
+ A* operator& () DELETE_FUNCTION;
private:
int int_;
char char_;
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
index f8f73f771356..88e6919526f9 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
@@ -19,6 +19,12 @@
#include "test_macros.h"
#include "count_new.hpp"
+#if TEST_STD_VER >= 11
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
+
struct A
{
static int count;
@@ -31,6 +37,9 @@ struct A
int get_int() const {return int_;}
char get_char() const {return char_;}
+
+ A* operator& () DELETE_FUNCTION;
+
private:
int int_;
char char_;
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
index d7e35a62f8f0..012741ff6c7d 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
@@ -254,9 +254,6 @@ int main()
// Use alignof(std::max_align_t) below to find the max alignment instead of
// hardcoding it, because it's different on different platforms.
// (For example 8 on arm and 16 on x86.)
-#if TEST_STD_VER < 11
-#define alignof __alignof__
-#endif
{
typedef std::aligned_storage<16>::type T1;
#if TEST_STD_VER > 11
@@ -264,7 +261,7 @@ int main()
#endif
static_assert(std::is_trivial<T1>::value, "");
static_assert(std::is_standard_layout<T1>::value, "");
- static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
+ static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
"");
static_assert(sizeof(T1) == 16, "");
}
@@ -275,9 +272,9 @@ int main()
#endif
static_assert(std::is_trivial<T1>::value, "");
static_assert(std::is_standard_layout<T1>::value, "");
- static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
+ static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
"");
- static_assert(sizeof(T1) == 16 + alignof(std::max_align_t), "");
+ static_assert(sizeof(T1) == 16 + TEST_ALIGNOF(std::max_align_t), "");
}
{
typedef std::aligned_storage<10>::type T1;
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/type_identity.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/type_identity.pass.cpp
new file mode 100644
index 000000000000..079986685a13
--- /dev/null
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/type_identity.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// type_traits
+
+// type_identity
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class T>
+void test_type_identity()
+{
+ static_assert((std::is_same<typename std::type_identity<T>::type, T>::value), "");
+ static_assert((std::is_same< std::type_identity_t<T>, T>::value), "");
+}
+
+int main()
+{
+ test_type_identity<void>();
+ test_type_identity<int>();
+ test_type_identity<const volatile int>();
+ test_type_identity<int*>();
+ test_type_identity< int[3]>();
+ test_type_identity<const int[3]>();
+
+ test_type_identity<void (*)()>();
+ test_type_identity<int(int) const>();
+ test_type_identity<int(int) volatile>();
+ test_type_identity<int(int) &>();
+ test_type_identity<int(int) &&>();
+}
diff --git a/test/std/utilities/meta/meta.type.synop/endian.pass.cpp b/test/std/utilities/meta/meta.type.synop/endian.pass.cpp
index cf0ab2d26390..865c477e7328 100644
--- a/test/std/utilities/meta/meta.type.synop/endian.pass.cpp
+++ b/test/std/utilities/meta/meta.type.synop/endian.pass.cpp
@@ -19,7 +19,6 @@
#include "test_macros.h"
int main() {
- typedef std::endian E;
static_assert(std::is_enum<std::endian>::value, "");
// Check that E is a scoped enum by checking for conversions.
diff --git a/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
index 0f55db64719b..bd02da96978d 100644
--- a/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
+++ b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
@@ -19,6 +19,9 @@
template <class T, unsigned A>
void test_alignment_of()
{
+ const unsigned AlignofResult = TEST_ALIGNOF(T);
+ static_assert( AlignofResult == A, "Golden value does not match result of alignof keyword");
+ static_assert( std::alignment_of<T>::value == AlignofResult, "");
static_assert( std::alignment_of<T>::value == A, "");
static_assert( std::alignment_of<const T>::value == A, "");
static_assert( std::alignment_of<volatile T>::value == A, "");
@@ -45,7 +48,10 @@ int main()
test_alignment_of<const int*, sizeof(intptr_t)>();
test_alignment_of<char[3], 1>();
test_alignment_of<int, 4>();
- test_alignment_of<double, 8>();
+ // The test case below is a hack. It's hard to detect what golden value
+ // we should expect. In most cases it should be 8. But in i386 builds
+ // with Clang >= 8 or GCC >= 8 the value is '4'.
+ test_alignment_of<double, TEST_ALIGNOF(double)>();
#if (defined(__ppc__) && !defined(__ppc64__))
test_alignment_of<bool, 4>(); // 32-bit PPC has four byte bool
#else
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp
index 09997626ea06..85c2c98173d9 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp
@@ -85,6 +85,9 @@ int main()
test_is_integral<signed char>();
test_is_integral<unsigned char>();
test_is_integral<wchar_t>();
+#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
+ test_is_integral<char8_t>();
+#endif
test_is_not_integral<std::nullptr_t>();
test_is_not_integral<void>();
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
index c89ac8944a93..9484b321c95c 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_default_constructible.pass.cpp
@@ -60,11 +60,22 @@ struct A
A();
};
+#if TEST_STD_VER >= 11
+struct DThrows
+{
+ DThrows() noexcept(true) {}
+ ~DThrows() noexcept(false) {}
+};
+#endif
+
int main()
{
test_has_not_nothrow_default_constructor<void>();
test_has_not_nothrow_default_constructor<int&>();
test_has_not_nothrow_default_constructor<A>();
+#if TEST_STD_VER >= 11
+ test_has_not_nothrow_default_constructor<DThrows>(); // This is LWG2116
+#endif
test_is_nothrow_default_constructible<Union>();
test_is_nothrow_default_constructible<Empty>();
diff --git a/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp b/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
index 198eee62bbba..8a73083487c0 100644
--- a/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
+++ b/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.7
+// XFAIL: availability=macosx10.8
// <optional>
diff --git a/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp b/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp
index d96f70bb7ba4..930015a7373f 100644
--- a/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp
+++ b/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp
@@ -9,6 +9,14 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// <optional>
// class bad_optional_access : public exception
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
index 98c90aa1d4fb..bec0f09a3e9a 100644
--- a/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
@@ -10,7 +10,7 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <optional>
-// optional<T>& operator=(const optional<T>& rhs);
+// optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20
#include <optional>
#include <type_traits>
@@ -53,15 +53,19 @@ int main()
{
{
using O = optional<int>;
+#if TEST_STD_VER > 17
LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+#endif
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
{
using O = optional<TrivialTestTypes::TestType>;
+#if TEST_STD_VER > 17
LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+#endif
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
index ed8b433da693..c41674f13cf2 100644
--- a/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
@@ -12,11 +12,12 @@
// optional<T>& operator=(optional<T>&& rhs)
// noexcept(is_nothrow_move_assignable<T>::value &&
-// is_nothrow_move_constructible<T>::value);
+// is_nothrow_move_constructible<T>::value); // constexpr in C++20
#include <optional>
-#include <type_traits>
#include <cassert>
+#include <type_traits>
+#include <utility>
#include "test_macros.h"
#include "archetypes.hpp"
@@ -51,6 +52,21 @@ struct Y {};
bool X::throw_now = false;
int X::alive = 0;
+
+template <class Tp>
+constexpr bool assign_empty(optional<Tp>&& lhs) {
+ optional<Tp> rhs;
+ lhs = std::move(rhs);
+ return !lhs.has_value() && !rhs.has_value();
+}
+
+template <class Tp>
+constexpr bool assign_value(optional<Tp>&& lhs) {
+ optional<Tp> rhs(101);
+ lhs = std::move(rhs);
+ return lhs.has_value() && rhs.has_value() && *lhs == Tp{101};
+}
+
int main()
{
{
@@ -97,6 +113,24 @@ int main()
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
assert(*opt == *opt2);
}
+ {
+ using O = optional<int>;
+#if TEST_STD_VER > 17
+ LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
+ LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+#endif
+ assert(assign_empty(O{42}));
+ assert(assign_value(O{42}));
+ }
+ {
+ using O = optional<TrivialTestTypes::TestType>;
+#if TEST_STD_VER > 17
+ LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
+ LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+#endif
+ assert(assign_empty(O{42}));
+ assert(assign_value(O{42}));
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
{
static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
index e4e4a979ed02..f1e9a1cfd9fa 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
@@ -9,12 +9,13 @@
//
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
index e9e98c0bdac6..ee0dcfd77da4 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -9,12 +9,13 @@
//
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp
deleted file mode 100644
index 77e411b2e3b5..000000000000
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.fail.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-// <optional>
-
-// constexpr optional(const optional<T>& rhs);
-// If is_trivially_copy_constructible_v<T> is true,
-// this constructor shall be a constexpr constructor.
-
-#include <optional>
-#include <type_traits>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct S {
- constexpr S() : v_(0) {}
- S(int v) : v_(v) {}
- S(const S &rhs) : v_(rhs.v_) {} // make it not trivially copyable
- int v_;
- };
-
-
-int main()
-{
- static_assert (!std::is_trivially_copy_constructible_v<S>, "" );
- constexpr std::optional<S> o1;
- constexpr std::optional<S> o2 = o1; // not constexpr
-}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
index 0f1fabd0cebb..31e7f9fdb54d 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -166,8 +166,8 @@ int main()
test_reference_extension();
}
{
- constexpr std::optional<int> o1{4};
- constexpr std::optional<int> o2 = o1;
- static_assert( *o2 == 4, "" );
+ constexpr std::optional<int> o1{4};
+ constexpr std::optional<int> o2 = o1;
+ static_assert( *o2 == 4, "" );
}
}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
index e73f3747c435..cb084ecd9242 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
index 761cbee4b895..f8a98508acb5 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -9,12 +9,13 @@
//
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
index bbc70014f099..f25bf71daf4b 100644
--- a/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp
index c644fb9d6696..00f934d6ae12 100644
--- a/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp
index 5347d3f558bb..90e8fb4565a0 100644
--- a/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp
@@ -9,12 +9,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <optional>
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp
index 1a577e68b99e..a63e3be8e4f6 100644
--- a/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <optional>
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// constexpr T& optional<T>::value() &&;
diff --git a/test/std/utilities/optional/optional.object/special_members.pass.cpp b/test/std/utilities/optional/optional.object/special_members.pass.cpp
new file mode 100644
index 000000000000..3bc561cfea3f
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/special_members.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <optional>
+
+// Make sure we properly generate special member functions for optional<T>
+// based on the properties of T itself.
+
+#include <optional>
+#include <type_traits>
+
+#include "archetypes.hpp"
+
+
+template <class T>
+struct SpecialMemberTest {
+ using O = std::optional<T>;
+
+ static_assert(std::is_default_constructible_v<O>,
+ "optional is always default constructible.");
+
+ static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
+ "optional<T> is copy constructible if and only if T is copy constructible.");
+
+ static_assert(std::is_move_constructible_v<O> ==
+ (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
+ "optional<T> is move constructible if and only if T is copy or move constructible.");
+
+ static_assert(std::is_copy_assignable_v<O> ==
+ (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
+ "optional<T> is copy assignable if and only if T is both copy "
+ "constructible and copy assignable.");
+
+ static_assert(std::is_move_assignable_v<O> ==
+ ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) ||
+ (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)),
+ "optional<T> is move assignable if and only if T is both move constructible and "
+ "move assignable, or both copy constructible and copy assignable.");
+};
+
+template <class ...Args> static void sink(Args&&...) {}
+
+template <class ...TestTypes>
+struct DoTestsMetafunction {
+ DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
+};
+
+int main() {
+ sink(
+ ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}
+ );
+}
diff --git a/test/std/utilities/optional/optional.object/triviality.pass.cpp b/test/std/utilities/optional/optional.object/triviality.pass.cpp
new file mode 100644
index 000000000000..c21c85aad962
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/triviality.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <optional>
+
+// The following special member functions should propagate the triviality of
+// the element held in the optional (see P0602R4):
+//
+// constexpr optional(const optional& rhs);
+// constexpr optional(optional&& rhs) noexcept(see below);
+// constexpr optional<T>& operator=(const optional& rhs);
+// constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
+
+
+#include <optional>
+#include <type_traits>
+
+#include "archetypes.hpp"
+
+
+constexpr bool implies(bool p, bool q) {
+ return !p || q;
+}
+
+template <class T>
+struct SpecialMemberTest {
+ using O = std::optional<T>;
+
+ static_assert(implies(std::is_trivially_copy_constructible_v<T>,
+ std::is_trivially_copy_constructible_v<O>),
+ "optional<T> is trivially copy constructible if T is trivially copy constructible.");
+
+ static_assert(implies(std::is_trivially_move_constructible_v<T>,
+ std::is_trivially_move_constructible_v<O>),
+ "optional<T> is trivially move constructible if T is trivially move constructible");
+
+ static_assert(implies(std::is_trivially_copy_constructible_v<T> &&
+ std::is_trivially_copy_assignable_v<T> &&
+ std::is_trivially_destructible_v<T>,
+
+ std::is_trivially_copy_assignable_v<O>),
+ "optional<T> is trivially copy assignable if T is "
+ "trivially copy constructible, "
+ "trivially copy assignable, and "
+ "trivially destructible");
+
+ static_assert(implies(std::is_trivially_move_constructible_v<T> &&
+ std::is_trivially_move_assignable_v<T> &&
+ std::is_trivially_destructible_v<T>,
+
+ std::is_trivially_move_assignable_v<O>),
+ "optional<T> is trivially move assignable if T is "
+ "trivially move constructible, "
+ "trivially move assignable, and"
+ "trivially destructible.");
+};
+
+template <class ...Args> static void sink(Args&&...) {}
+
+template <class ...TestTypes>
+struct DoTestsMetafunction {
+ DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
+};
+
+struct TrivialMoveNonTrivialCopy {
+ TrivialMoveNonTrivialCopy() = default;
+ TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
+ TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
+ TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
+ TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
+};
+
+struct TrivialCopyNonTrivialMove {
+ TrivialCopyNonTrivialMove() = default;
+ TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
+ TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
+ TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
+ TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
+};
+
+int main() {
+ sink(
+ ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
+ DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
+ );
+}
diff --git a/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
index 3fbf19f8ee1b..421480aa8c03 100644
--- a/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
+++ b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
@@ -10,6 +10,14 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// <optional>
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// template <class T>
// constexpr optional<decay_t<T>> make_optional(T&& v);
diff --git a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
index 9908811cf3d2..fb47e0cfb3af 100644
--- a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
@@ -12,6 +12,7 @@
#include <bitset>
#include <cstdlib>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
index 6847694e4b73..e1bf6b8763bb 100644
--- a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
@@ -11,6 +11,7 @@
#include <bitset>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
index 1c8d6a1c32a4..e46ed978d8a8 100644
--- a/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
@@ -11,6 +11,7 @@
#include <bitset>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
index 084dc9f8d46f..4a1c0e23bc4d 100644
--- a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
@@ -12,6 +12,7 @@
#include <bitset>
#include <cstdlib>
#include <cassert>
+#include <stdexcept>
#include "test_macros.h"
diff --git a/test/std/utilities/template.bitset/includes.pass.cpp b/test/std/utilities/template.bitset/includes.pass.cpp
index e640a1b5b7ed..021ca28e63e2 100644
--- a/test/std/utilities/template.bitset/includes.pass.cpp
+++ b/test/std/utilities/template.bitset/includes.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// test that <bitset> includes <cstddef>, <string>, <stdexcept> and <iosfwd>
+// test that <bitset> includes <string> and <iosfwd>
#include <bitset>
@@ -15,18 +15,9 @@ template <class> void test_typedef() {}
int main()
{
- { // test for <cstddef>
- std::ptrdiff_t p; ((void)p);
- std::size_t s; ((void)s);
- std::nullptr_t np; ((void)np);
- }
{ // test for <string>
std::string s; ((void)s);
}
- { // test for <stdexcept>
- std::logic_error le("blah"); ((void)le);
- std::runtime_error re("blah"); ((void)re);
- }
{ // test for <iosfwd>
test_typedef<std::ios>();
test_typedef<std::wios>();
diff --git a/test/std/utilities/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp
index fe9f38daa3ff..f6dd75d2484a 100644
--- a/test/std/utilities/time/date.time/ctime.pass.cpp
+++ b/test/std/utilities/time/date.time/ctime.pass.cpp
@@ -26,6 +26,10 @@
#endif
#endif
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wformat-zero-length"
+#endif
+
int main()
{
std::clock_t c = 0;
@@ -47,7 +51,7 @@ int main()
static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), "");
static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), "");
static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
-#if TEST_STD_VER > 14 && defined(TEST_HAS_C11_FEATURES)
+#if TEST_STD_VER > 14 && defined(TEST_HAS_TIMESPEC_GET)
static_assert((std::is_same<decltype(std::timespec_get(nullptr, 0)), int>::value), "");
#endif
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
diff --git a/test/std/utilities/time/days.pass.cpp b/test/std/utilities/time/days.pass.cpp
new file mode 100644
index 000000000000..14ab01a65c5f
--- /dev/null
+++ b/test/std/utilities/time/days.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// using days = duration<signed integer type of at least 25 bits, ratio_multiply<ratio<24>, hours::period>>;
+
+#include <chrono>
+#include <type_traits>
+#include <limits>
+
+int main()
+{
+ typedef std::chrono::days D;
+ typedef D::rep Rep;
+ typedef D::period Period;
+ static_assert(std::is_signed<Rep>::value, "");
+ static_assert(std::is_integral<Rep>::value, "");
+ static_assert(std::numeric_limits<Rep>::digits >= 25, "");
+ static_assert(std::is_same_v<Period, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>, "");
+}
diff --git a/test/std/utilities/time/months.pass.cpp b/test/std/utilities/time/months.pass.cpp
new file mode 100644
index 000000000000..63f85623e873
--- /dev/null
+++ b/test/std/utilities/time/months.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// using months = duration<signed integer type of at least 20 bits, ratio_divide<years::period, ratio<12>>>;
+
+
+#include <chrono>
+#include <type_traits>
+#include <limits>
+
+int main()
+{
+ typedef std::chrono::months D;
+ typedef D::rep Rep;
+ typedef D::period Period;
+ static_assert(std::is_signed<Rep>::value, "");
+ static_assert(std::is_integral<Rep>::value, "");
+ static_assert(std::numeric_limits<Rep>::digits >= 20, "");
+ static_assert(std::is_same_v<Period, std::ratio_divide<std::chrono::years::period, std::ratio<12>>>, "");
+}
diff --git a/test/std/utilities/time/time.cal/euclidian.h b/test/std/utilities/time/time.cal/euclidian.h
new file mode 100644
index 000000000000..cc7e054ac552
--- /dev/null
+++ b/test/std/utilities/time/time.cal/euclidian.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// Assumption: minValue < maxValue
+// Assumption: minValue <= rhs <= maxValue
+// Assumption: minValue <= lhs <= maxValue
+// Assumption: minValue >= 0
+template <typename T, T minValue, T maxValue>
+T euclidian_addition(T rhs, T lhs)
+{
+ const T modulus = maxValue - minValue + 1;
+ T ret = rhs + lhs;
+ if (ret > maxValue)
+ ret -= modulus;
+ return ret;
+}
+
+// Assumption: minValue < maxValue
+// Assumption: minValue <= rhs <= maxValue
+// Assumption: minValue <= lhs <= maxValue
+// Assumption: minValue >= 0
+template <typename T, T minValue, T maxValue>
+T euclidian_subtraction(T lhs, T rhs)
+{
+ const T modulus = maxValue - minValue + 1;
+ T ret = lhs - rhs;
+ if (ret < minValue)
+ ret += modulus;
+ if (ret > maxValue) // this can happen if T is unsigned
+ ret += modulus;
+ return ret;
+}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/std/utilities/time/time.cal/nothing_to_do.pass.cpp
index b58f5c55b643..b58f5c55b643 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
+++ b/test/std/utilities/time/time.cal/nothing_to_do.pass.cpp
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ctor.pass.cpp
new file mode 100644
index 000000000000..dd36ee5747f5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ctor.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// day() = default;
+// explicit constexpr day(unsigned d) noexcept;
+// explicit constexpr operator unsigned() const noexcept;
+
+// Effects: Constructs an object of type day by initializing d_ with d.
+// The value held is unspecified if d is not in the range [0, 255].
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+
+ ASSERT_NOEXCEPT(day{});
+ ASSERT_NOEXCEPT(day(0U));
+ ASSERT_NOEXCEPT(static_cast<unsigned>(day(0U)));
+
+ constexpr day d0{};
+ static_assert(static_cast<unsigned>(d0) == 0, "");
+
+ constexpr day d1{1};
+ static_assert(static_cast<unsigned>(d1) == 1, "");
+
+ for (unsigned i = 0; i <= 255; ++i)
+ {
+ day day(i);
+ assert(static_cast<unsigned>(day) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/decrement.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/decrement.pass.cpp
new file mode 100644
index 000000000000..a3ac8dc46cb9
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/decrement.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr day& operator--() noexcept;
+// constexpr day operator--(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D>
+constexpr bool testConstexpr()
+{
+ D d1{10};
+ if (static_cast<unsigned>(--d1) != 9) return false;
+ if (static_cast<unsigned>(d1--) != 9) return false;
+ if (static_cast<unsigned>(d1) != 8) return false;
+ return true;
+}
+
+int main()
+{
+ using day = std::chrono::day;
+ ASSERT_NOEXCEPT(--(std::declval<day&>()) );
+ ASSERT_NOEXCEPT( (std::declval<day&>())--);
+
+ ASSERT_SAME_TYPE(day , decltype( std::declval<day&>()--));
+ ASSERT_SAME_TYPE(day&, decltype(--std::declval<day&>() ));
+
+ static_assert(testConstexpr<day>(), "");
+
+ for (unsigned i = 10; i <= 20; ++i)
+ {
+ day day(i);
+ assert(static_cast<unsigned>(--day) == i - 1);
+ assert(static_cast<unsigned>(day--) == i - 1);
+ assert(static_cast<unsigned>(day) == i - 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/increment.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/increment.pass.cpp
new file mode 100644
index 000000000000..aa084e863396
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/increment.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr day& operator++() noexcept;
+// constexpr day operator++(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D>
+constexpr bool testConstexpr()
+{
+ D d1{1};
+ if (static_cast<unsigned>(++d1) != 2) return false;
+ if (static_cast<unsigned>(d1++) != 2) return false;
+ if (static_cast<unsigned>(d1) != 3) return false;
+ return true;
+}
+
+int main()
+{
+ using day = std::chrono::day;
+ ASSERT_NOEXCEPT(++(std::declval<day&>()) );
+ ASSERT_NOEXCEPT( (std::declval<day&>())++);
+
+ ASSERT_SAME_TYPE(day , decltype( std::declval<day&>()++));
+ ASSERT_SAME_TYPE(day&, decltype(++std::declval<day&>() ));
+
+ static_assert(testConstexpr<day>(), "");
+
+ for (unsigned i = 10; i <= 20; ++i)
+ {
+ day day(i);
+ assert(static_cast<unsigned>(++day) == i + 1);
+ assert(static_cast<unsigned>(day++) == i + 1);
+ assert(static_cast<unsigned>(day) == i + 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ok.pass.cpp
new file mode 100644
index 000000000000..54b18e34b8be
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ok.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr bool ok() const noexcept;
+// Returns: 1 <= d_ && d_ <= 31
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ ASSERT_NOEXCEPT( std::declval<const day>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const day>().ok()));
+
+ static_assert(!day{0}.ok(), "");
+ static_assert( day{1}.ok(), "");
+
+ assert(!day{0}.ok());
+ for (unsigned i = 1; i <= 31; ++i)
+ assert(day{i}.ok());
+ for (unsigned i = 32; i <= 255; ++i)
+ assert(!day{i}.ok());
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/plus_minus_equal.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/plus_minus_equal.pass.cpp
new file mode 100644
index 000000000000..aed46e7d7c73
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/plus_minus_equal.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr day& operator+=(const days& d) noexcept;
+// constexpr day& operator-=(const days& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr()
+{
+ D d1{1};
+ if (static_cast<unsigned>(d1 += Ds{ 1}) != 2) return false;
+ if (static_cast<unsigned>(d1 += Ds{ 2}) != 4) return false;
+ if (static_cast<unsigned>(d1 += Ds{22}) != 26) return false;
+ if (static_cast<unsigned>(d1 -= Ds{ 1}) != 25) return false;
+ if (static_cast<unsigned>(d1 -= Ds{ 2}) != 23) return false;
+ if (static_cast<unsigned>(d1 -= Ds{22}) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using day = std::chrono::day;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT(std::declval<day&>() += std::declval<days>());
+ ASSERT_NOEXCEPT(std::declval<day&>() -= std::declval<days>());
+
+ ASSERT_SAME_TYPE(day&, decltype(std::declval<day&>() += std::declval<days>()));
+ ASSERT_SAME_TYPE(day&, decltype(std::declval<day&>() -= std::declval<days>()));
+
+ static_assert(testConstexpr<day, days>(), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ day day(i);
+ assert(static_cast<unsigned>(day += days{22}) == i + 22);
+ assert(static_cast<unsigned>(day) == i + 22);
+ assert(static_cast<unsigned>(day -= days{12}) == i + 10);
+ assert(static_cast<unsigned>(day) == i + 10);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..1047e1bc33ed
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr bool operator==(const day& x, const day& y) noexcept;
+// Returns: unsigned{x} == unsigned{y}.
+// constexpr bool operator<(const day& x, const day& y) noexcept;
+// Returns: unsigned{x} < unsigned{y}.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using day = std::chrono::day;
+
+ AssertComparisons6AreNoexcept<day>();
+ AssertComparisons6ReturnBool<day>();
+
+ static_assert(testComparisons6Values<day>(0U, 0U), "");
+ static_assert(testComparisons6Values<day>(0U, 1U), "");
+
+// Some 'ok' values as well
+ static_assert(testComparisons6Values<day>( 5U, 5U), "");
+ static_assert(testComparisons6Values<day>( 5U, 10U), "");
+
+ for (unsigned i = 1; i < 10; ++i)
+ for (unsigned j = 1; j < 10; ++j)
+ assert(testComparisons6Values<day>(i, j));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.fail.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.fail.cpp
new file mode 100644
index 000000000000..350a846353a0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.fail.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-5, clang-6
+// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
+
+// <chrono>
+// class day;
+
+// constexpr day operator""d(unsigned long long d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ day d1 = 4d; // expected-error-re {{no matching literal operator for call to 'operator""d' {{.*}}}}
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp
new file mode 100644
index 000000000000..405200e470d8
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-5, clang-6, clang-7
+// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
+
+// <chrono>
+// class day;
+
+// constexpr day operator""d(unsigned long long d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ {
+ using namespace std::chrono;
+ ASSERT_NOEXCEPT( 4d);
+ ASSERT_SAME_TYPE(day, decltype(4d));
+
+ static_assert( 7d == day(7), "");
+ day d1 = 4d;
+ assert (d1 == day(4));
+}
+
+ {
+ using namespace std::literals;
+ ASSERT_NOEXCEPT( 4d);
+ ASSERT_SAME_TYPE(std::chrono::day, decltype(4d));
+
+ static_assert( 7d == std::chrono::day(7), "");
+
+ std::chrono::day d1 = 4d;
+ assert (d1 == std::chrono::day(4));
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..47ef42c07bac
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/minus.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr day operator-(const day& x, const days& y) noexcept;
+// Returns: x + -y.
+//
+// constexpr days operator-(const day& x, const day& y) noexcept;
+// Returns: days{int(unsigned{x}) - int(unsigned{y}).
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr()
+{
+ D d{23};
+ Ds offset{6};
+ if (d - offset != D{17}) return false;
+ if (d - D{17} != offset) return false;
+ return true;
+}
+
+int main()
+{
+ using day = std::chrono::day;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT(std::declval<day>() - std::declval<days>());
+ ASSERT_NOEXCEPT(std::declval<day>() - std::declval<day>());
+
+ ASSERT_SAME_TYPE(day, decltype(std::declval<day>() - std::declval<days>()));
+ ASSERT_SAME_TYPE(days, decltype(std::declval<day>() - std::declval<day>()));
+
+ static_assert(testConstexpr<day, days>(), "");
+
+ day dy{12};
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ day d1 = dy - days{i};
+ days off = dy - day {i};
+ assert(static_cast<unsigned>(d1) == 12 - i);
+ assert(off.count() == static_cast<int>(12 - i)); // days is signed
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..b08d6ef4b5c1
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/plus.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+// constexpr day operator+(const day& x, const days& y) noexcept;
+// Returns: day(unsigned{x} + y.count()).
+//
+// constexpr day operator+(const days& x, const day& y) noexcept;
+// Returns: y + x.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr()
+{
+ D d{1};
+ Ds offset{23};
+ if (d + offset != D{24}) return false;
+ if (offset + d != D{24}) return false;
+ return true;
+}
+
+int main()
+{
+ using day = std::chrono::day;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT(std::declval<day>() + std::declval<days>());
+ ASSERT_NOEXCEPT(std::declval<days>() + std::declval<day>());
+
+ ASSERT_SAME_TYPE(day, decltype(std::declval<day>() + std::declval<days>()));
+ ASSERT_SAME_TYPE(day, decltype(std::declval<days>() + std::declval<day>()));
+
+ static_assert(testConstexpr<day, days>(), "");
+
+ day dy{12};
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ day d1 = dy + days{i};
+ day d2 = days{i} + dy;
+ assert(d1 == d2);
+ assert(static_cast<unsigned>(d1) == i + 12);
+ assert(static_cast<unsigned>(d2) == i + 12);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..9c949170af73
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class day;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const day& d);
+//
+// Effects: Inserts format(fmt, d) where fmt is "%d" widened to charT.
+// If !d.ok(), appends with " is not a valid day".
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const day& d);
+//
+// Effects: Streams d into os using the format specified by the NTCTS fmt.
+// fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// day& d, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the day d using the format flags
+// given in the NTCTS fmt as specified in 25.12.
+// If the parse fails to decode a valid day, is.setstate(ios_base::failbit)
+// shall be called and d shall not be modified.
+// If %Z is used and successfully parsed, that value will be assigned to *abbrev
+// if abbrev is non-null. If %z (or a modified variant) is used and
+// successfully parsed, that value will be assigned to *offset if offset is non-null.
+//
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ std::cout << day{1};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.day/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/types.pass.cpp
new file mode 100644
index 000000000000..06b70b0aa890
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.day/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class day;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+
+ static_assert(std::is_trivially_copyable_v<day>, "");
+ static_assert(std::is_standard_layout_v<day>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.last/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.last/types.pass.cpp
new file mode 100644
index 000000000000..5d85120580e6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.last/types.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// struct last_spec {
+// explicit last_spec() = default;
+// };
+//
+// inline constexpr last_spec last{};
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using last_spec = std::chrono::last_spec;
+
+ ASSERT_SAME_TYPE(const last_spec, decltype(std::chrono::last));
+
+ static_assert(std::is_trivially_copyable_v<last_spec>, "");
+ static_assert(std::is_standard_layout_v<last_spec>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ctor.pass.cpp
new file mode 100644
index 000000000000..743da74ba46f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ctor.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// month_day() = default;
+// constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept;
+//
+// Effects: Constructs an object of type month_day by initializing m_ with m, and d_ with d.
+//
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::day day() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using month = std::chrono::month;
+ using month_day = std::chrono::month_day;
+
+ ASSERT_NOEXCEPT(month_day{});
+ ASSERT_NOEXCEPT(month_day{month{1}, day{1}});
+
+ constexpr month_day md0{};
+ static_assert( md0.month() == month{}, "");
+ static_assert( md0.day() == day{}, "");
+ static_assert(!md0.ok(), "");
+
+ constexpr month_day md1{std::chrono::January, day{4}};
+ static_assert( md1.month() == std::chrono::January, "");
+ static_assert( md1.day() == day{4}, "");
+ static_assert( md1.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/day.pass.cpp
new file mode 100644
index 000000000000..5bc001c47464
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/day.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using month_day = std::chrono::month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const month_day>().day());
+ ASSERT_SAME_TYPE(day, decltype(std::declval<const month_day>().day()));
+
+ static_assert( month_day{}.day() == day{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_day md(std::chrono::March, day{i});
+ assert( static_cast<unsigned>(md.day()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/month.pass.cpp
new file mode 100644
index 000000000000..96806fda8ea7
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/month.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using month = std::chrono::month;
+ using month_day = std::chrono::month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const month_day>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const month_day>().month()));
+
+ static_assert( month_day{}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_day md(month{i}, day{1});
+ assert( static_cast<unsigned>(md.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ok.pass.cpp
new file mode 100644
index 000000000000..d715635d423e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ok.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// constexpr bool ok() const noexcept;
+// Returns: true if m_.ok() is true, 1d <= d_, and d_ is less than or equal to the
+// number of days in month m_; otherwise returns false.
+// When m_ == February, the number of days is considered to be 29.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using month = std::chrono::month;
+ using month_day = std::chrono::month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const month_day>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const month_day>().ok()));
+
+ static_assert(!month_day{}.ok(), "");
+ static_assert( month_day{std::chrono::May, day{2}}.ok(), "");
+
+ assert(!(month_day(std::chrono::April, day{0}).ok()));
+
+ assert( (month_day{std::chrono::March, day{1}}.ok()));
+ for (unsigned i = 1; i <= 12; ++i)
+ {
+ const bool is31 = i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12;
+ assert(!(month_day{month{i}, day{ 0}}.ok()));
+ assert( (month_day{month{i}, day{ 1}}.ok()));
+ assert( (month_day{month{i}, day{10}}.ok()));
+ assert( (month_day{month{i}, day{29}}.ok()));
+ assert( (month_day{month{i}, day{30}}.ok()) == (i != 2));
+ assert( (month_day{month{i}, day{31}}.ok()) == is31);
+ assert(!(month_day{month{i}, day{32}}.ok()));
+ }
+
+// If the month is not ok, all the days are bad
+ for (unsigned i = 1; i <= 35; ++i)
+ assert(!(month_day{month{13}, day{i}}.ok()));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..c8938be082a5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
+// Returns: x.month() == y.month() && x.day() == y.day().
+//
+// constexpr bool operator< (const month_day& x, const month_day& y) noexcept;
+// Returns:
+// If x.month() < y.month() returns true.
+// Otherwise, if x.month() > y.month() returns false.
+// Otherwise, returns x.day() < y.day().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using month = std::chrono::month;
+ using month_day = std::chrono::month_day;
+
+ AssertComparisons6AreNoexcept<month_day>();
+ AssertComparisons6ReturnBool<month_day>();
+
+ static_assert( testComparisons6(
+ month_day{std::chrono::January, day{1}},
+ month_day{std::chrono::January, day{1}},
+ true, false), "");
+
+ static_assert( testComparisons6(
+ month_day{std::chrono::January, day{1}},
+ month_day{std::chrono::January, day{2}},
+ false, true), "");
+
+ static_assert( testComparisons6(
+ month_day{std::chrono::January, day{1}},
+ month_day{std::chrono::February, day{1}},
+ false, true), "");
+
+// same day, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons6(
+ month_day{month{i}, day{1}},
+ month_day{month{j}, day{1}},
+ i == j, i < j )));
+
+// same month, different days
+ for (unsigned i = 1; i < 31; ++i)
+ for (unsigned j = 1; j < 31; ++j)
+ assert((testComparisons6(
+ month_day{month{2}, day{i}},
+ month_day{month{2}, day{j}},
+ i == j, i < j )));
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..46ae31aaf8d6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class month_day;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const month_day& md);
+//
+// Returns: os << md.month() << '/' << md.day().
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const month_day& md);
+//
+// Effects: Streams md into os using the format specified by the NTCTS fmt.
+// fmt encoding follows the rules specified in 25.11.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+#include "test_macros.h"
+
+int main()
+{
+ using month_day = std::chrono::month_day;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ std::cout << month_day{month{1}, day{1}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.md/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.md/types.pass.cpp
new file mode 100644
index 000000000000..988e43323c2a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.md/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_day = std::chrono::month_day;
+
+ static_assert(std::is_trivially_copyable_v<month_day>, "");
+ static_assert(std::is_standard_layout_v<month_day>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/comparisons.pass.cpp
new file mode 100644
index 000000000000..c3bc1777dea5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/comparisons.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day_last;
+
+// constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
+// Returns: x.month() == y.month()
+//
+// constexpr bool operator< (const month_day& x, const month_day& y) noexcept;
+// Returns: x.month() < y.month()
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ AssertComparisons6AreNoexcept<month_day_last>();
+ AssertComparisons6ReturnBool<month_day_last>();
+
+ static_assert( testComparisons6Values<month_day_last>(month{1}, month{1}), "");
+ static_assert( testComparisons6Values<month_day_last>(month{1}, month{2}), "");
+
+// same day, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons6Values<month_day_last>(month{i}, month{j})));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/ctor.pass.cpp
new file mode 100644
index 000000000000..5ae3294402b5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/ctor.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day_last;
+
+// constexpr month_day_last(const chrono::month& m) noexcept;
+//
+// Effects: Constructs an object of type month_day_last by initializing m_ with m
+//
+// constexpr chrono::month month() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ ASSERT_NOEXCEPT(month_day_last{month{1}});
+
+ constexpr month_day_last md0{month{}};
+ static_assert( md0.month() == month{}, "");
+ static_assert(!md0.ok(), "");
+
+ constexpr month_day_last md1{std::chrono::January};
+ static_assert( md1.month() == std::chrono::January, "");
+ static_assert( md1.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/month.pass.cpp
new file mode 100644
index 000000000000..421f9e7b0a2b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/month.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day_last;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: m_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const month_day_last>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const month_day_last>().month()));
+
+ static_assert( month_day_last{month{}}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_day_last mdl(month{i});
+ assert( static_cast<unsigned>(mdl.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/ok.pass.cpp
new file mode 100644
index 000000000000..85955c819c56
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/ok.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day_last;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const month_day_last>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const month_day_last>().ok()));
+
+ static_assert(!month_day_last{month{}}.ok(), "");
+ static_assert( month_day_last{std::chrono::May}.ok(), "");
+
+ for (unsigned i = 1; i <= 12; ++i)
+ {
+ month_day_last mdl{month{i}};
+ assert( mdl.ok());
+ }
+
+// If the month is not ok, all the days are bad
+ for (unsigned i = 13; i <= 50; ++i)
+ {
+ month_day_last mdl{month{i}};
+ assert(!mdl.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp
new file mode 100644
index 000000000000..3c2da00e803a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class month_day_last;
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);
+//
+// Returns: os << mdl.month() << "/last".
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_day_last = std::chrono::month_day_last;
+ using month = std::chrono::month;
+ std::cout << month_day_last{month{1}};
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.fail.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp
index c3cabbdb79d5..de15cabd070d 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.fail.cpp
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp
@@ -1,4 +1,3 @@
-// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -7,19 +6,22 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// <new>
-
-// void* operator new(std::size_t, std::align_val_t);
+// <chrono>
-// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8
+// class month_day_last;
-#include <new>
+#include <chrono>
+#include <type_traits>
+#include <cassert>
#include "test_macros.h"
-int main ()
+int main()
{
- ::operator new(4, std::align_val_t{4}); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}}
+ using month_day_last = std::chrono::month_day_last;
+
+ static_assert(std::is_trivially_copyable_v<month_day_last>, "");
+ static_assert(std::is_standard_layout_v<month_day_last>, "");
}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ctor.pass.cpp
new file mode 100644
index 000000000000..5e86f58ec9d0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ctor.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// month() = default;
+// explicit constexpr month(int m) noexcept;
+// explicit constexpr operator int() const noexcept;
+
+// Effects: Constructs an object of type month by initializing m_ with m.
+// The value held is unspecified if d is not in the range [0, 255].
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+
+ ASSERT_NOEXCEPT(month{});
+ ASSERT_NOEXCEPT(month(1));
+ ASSERT_NOEXCEPT(static_cast<unsigned>(month(1)));
+
+ constexpr month m0{};
+ static_assert(static_cast<unsigned>(m0) == 0, "");
+
+ constexpr month m1{1};
+ static_assert(static_cast<unsigned>(m1) == 1, "");
+
+ for (unsigned i = 0; i <= 255; ++i)
+ {
+ month m(i);
+ assert(static_cast<unsigned>(m) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/decrement.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/decrement.pass.cpp
new file mode 100644
index 000000000000..b6d4848fbf9a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/decrement.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr month& operator--() noexcept;
+// constexpr month operator--(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename M>
+constexpr bool testConstexpr()
+{
+ M m1{10};
+ if (static_cast<unsigned>(--m1) != 9) return false;
+ if (static_cast<unsigned>(m1--) != 9) return false;
+ if (static_cast<unsigned>(m1) != 8) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+
+ ASSERT_NOEXCEPT(--(std::declval<month&>()) );
+ ASSERT_NOEXCEPT( (std::declval<month&>())--);
+
+ ASSERT_SAME_TYPE(month , decltype( std::declval<month&>()--));
+ ASSERT_SAME_TYPE(month&, decltype(--std::declval<month&>() ));
+
+ static_assert(testConstexpr<month>(), "");
+
+ for (unsigned i = 10; i <= 20; ++i)
+ {
+ month month(i);
+ assert(static_cast<unsigned>(--month) == i - 1);
+ assert(static_cast<unsigned>(month--) == i - 1);
+ assert(static_cast<unsigned>(month) == i - 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/increment.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/increment.pass.cpp
new file mode 100644
index 000000000000..2309490abb82
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/increment.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr month& operator++() noexcept;
+// constexpr month operator++(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename M>
+constexpr bool testConstexpr()
+{
+ M m1{1};
+ if (static_cast<unsigned>(++m1) != 2) return false;
+ if (static_cast<unsigned>(m1++) != 2) return false;
+ if (static_cast<unsigned>(m1) != 3) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+ ASSERT_NOEXCEPT(++(std::declval<month&>()) );
+ ASSERT_NOEXCEPT( (std::declval<month&>())++);
+
+ ASSERT_SAME_TYPE(month , decltype( std::declval<month&>()++));
+ ASSERT_SAME_TYPE(month&, decltype(++std::declval<month&>() ));
+
+ static_assert(testConstexpr<month>(), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ month month(i);
+ assert(static_cast<unsigned>(++month) == i + 1);
+ assert(static_cast<unsigned>(month++) == i + 1);
+ assert(static_cast<unsigned>(month) == i + 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ok.pass.cpp
new file mode 100644
index 000000000000..3382a6378565
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ok.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr bool ok() const noexcept;
+// Returns: 1 <= d_ && d_ <= 12
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+
+ ASSERT_NOEXCEPT( std::declval<const month>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const month>().ok()));
+
+ static_assert(!month{0}.ok(), "");
+ static_assert( month{1}.ok(), "");
+
+ assert(!month{0}.ok());
+ for (unsigned i = 1; i <= 12; ++i)
+ assert(month{i}.ok());
+ for (unsigned i = 13; i <= 255; ++i)
+ assert(!month{i}.ok());
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/plus_minus_equal.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/plus_minus_equal.pass.cpp
new file mode 100644
index 000000000000..1e5a045ed4af
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/plus_minus_equal.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr month& operator+=(const month& d) noexcept;
+// constexpr month& operator-=(const month& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename M, typename Ms>
+constexpr bool testConstexpr()
+{
+ M m1{1};
+ if (static_cast<unsigned>(m1 += Ms{ 1}) != 2) return false;
+ if (static_cast<unsigned>(m1 += Ms{ 2}) != 4) return false;
+ if (static_cast<unsigned>(m1 += Ms{ 8}) != 12) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 1}) != 11) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 2}) != 9) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 8}) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<month&>() += std::declval<months&>());
+ ASSERT_NOEXCEPT(std::declval<month&>() -= std::declval<months&>());
+ ASSERT_SAME_TYPE(month&, decltype(std::declval<month&>() += std::declval<months&>()));
+ ASSERT_SAME_TYPE(month&, decltype(std::declval<month&>() -= std::declval<months&>()));
+
+ static_assert(testConstexpr<month, months>(), "");
+
+ for (unsigned i = 1; i <= 10; ++i)
+ {
+ month month(i);
+ int exp = i + 10;
+ while (exp > 12)
+ exp -= 12;
+ assert(static_cast<unsigned>(month += months{10}) == static_cast<unsigned>(exp));
+ assert(static_cast<unsigned>(month) == static_cast<unsigned>(exp));
+ }
+
+ for (unsigned i = 1; i <= 10; ++i)
+ {
+ month month(i);
+ int exp = i - 9;
+ while (exp < 1)
+ exp += 12;
+ assert(static_cast<unsigned>(month -= months{ 9}) == static_cast<unsigned>(exp));
+ assert(static_cast<unsigned>(month) == static_cast<unsigned>(exp));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..21c6e0027b63
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr bool operator==(const month& x, const month& y) noexcept;
+// constexpr bool operator!=(const month& x, const month& y) noexcept;
+// constexpr bool operator< (const month& x, const month& y) noexcept;
+// constexpr bool operator> (const month& x, const month& y) noexcept;
+// constexpr bool operator<=(const month& x, const month& y) noexcept;
+// constexpr bool operator>=(const month& x, const month& y) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+
+int main()
+{
+ using month = std::chrono::month;
+
+ AssertComparisons6AreNoexcept<month>();
+ AssertComparisons6ReturnBool<month>();
+
+ static_assert(testComparisons6Values<month>(0U ,0U), "");
+ static_assert(testComparisons6Values<month>(0U, 1U), "");
+
+// Some 'ok' values as well
+ static_assert(testComparisons6Values<month>( 5U, 5U), "");
+ static_assert(testComparisons6Values<month>( 5U, 10U), "");
+
+ for (unsigned i = 1; i < 10; ++i)
+ for (unsigned j = 10; j < 10; ++j)
+ assert(testComparisons6Values<month>(i, j));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/literals.pass.cpp
new file mode 100644
index 000000000000..2721a97666b6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/literals.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// 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};
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::January));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::February));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::March));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::April));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::May));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::June));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::July));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::August));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::September));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::October));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::November));
+ ASSERT_SAME_TYPE(const std::chrono::month, decltype(std::chrono::December));
+
+ static_assert( std::chrono::January == std::chrono::month(1), "");
+ static_assert( std::chrono::February == std::chrono::month(2), "");
+ static_assert( std::chrono::March == std::chrono::month(3), "");
+ static_assert( std::chrono::April == std::chrono::month(4), "");
+ static_assert( std::chrono::May == std::chrono::month(5), "");
+ static_assert( std::chrono::June == std::chrono::month(6), "");
+ static_assert( std::chrono::July == std::chrono::month(7), "");
+ static_assert( std::chrono::August == std::chrono::month(8), "");
+ static_assert( std::chrono::September == std::chrono::month(9), "");
+ static_assert( std::chrono::October == std::chrono::month(10), "");
+ static_assert( std::chrono::November == std::chrono::month(11), "");
+ static_assert( std::chrono::December == std::chrono::month(12), "");
+
+ assert(std::chrono::January == std::chrono::month(1));
+ assert(std::chrono::February == std::chrono::month(2));
+ assert(std::chrono::March == std::chrono::month(3));
+ assert(std::chrono::April == std::chrono::month(4));
+ assert(std::chrono::May == std::chrono::month(5));
+ assert(std::chrono::June == std::chrono::month(6));
+ assert(std::chrono::July == std::chrono::month(7));
+ assert(std::chrono::August == std::chrono::month(8));
+ assert(std::chrono::September == std::chrono::month(9));
+ assert(std::chrono::October == std::chrono::month(10));
+ assert(std::chrono::November == std::chrono::month(11));
+ assert(std::chrono::December == std::chrono::month(12));
+
+ assert(static_cast<unsigned>(std::chrono::January) == 1);
+ assert(static_cast<unsigned>(std::chrono::February) == 2);
+ assert(static_cast<unsigned>(std::chrono::March) == 3);
+ assert(static_cast<unsigned>(std::chrono::April) == 4);
+ assert(static_cast<unsigned>(std::chrono::May) == 5);
+ assert(static_cast<unsigned>(std::chrono::June) == 6);
+ assert(static_cast<unsigned>(std::chrono::July) == 7);
+ assert(static_cast<unsigned>(std::chrono::August) == 8);
+ assert(static_cast<unsigned>(std::chrono::September) == 9);
+ assert(static_cast<unsigned>(std::chrono::October) == 10);
+ assert(static_cast<unsigned>(std::chrono::November) == 11);
+ assert(static_cast<unsigned>(std::chrono::December) == 12);
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..1329a9f956be
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr month operator-(const month& x, const months& y) noexcept;
+// Returns: x + -y.
+//
+// constexpr months operator-(const month& x, const month& y) noexcept;
+// Returns: If x.ok() == true and y.ok() == true, returns a value m in the range
+// [months{0}, months{11}] satisfying y + m == x.
+// Otherwise the value returned is unspecified.
+// [Example: January - February == months{11}. —end example]
+
+extern "C" int printf(const char *, ...);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename M, typename Ms>
+constexpr bool testConstexpr()
+{
+ {
+ M m{5};
+ Ms offset{3};
+ if (m - offset != M{2}) return false;
+ if (m - M{2} != offset) return false;
+ }
+
+// Check the example
+ if (M{1} - M{2} != Ms{11}) return false;
+ return true;
+}
+
+#include <iostream>
+
+int main()
+{
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<month>() - std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<month>() - std::declval<month>());
+
+ ASSERT_SAME_TYPE(month , decltype(std::declval<month>() - std::declval<months>()));
+ ASSERT_SAME_TYPE(months, decltype(std::declval<month>() - std::declval<month> ()));
+
+static_assert(testConstexpr<month, months>(), "");
+
+ month m{6};
+ for (unsigned i = 1; i <= 12; ++i)
+ {
+ month m1 = m - months{i};
+// months off = m - month {i};
+ int exp = 6 - i;
+ if (exp < 1)
+ exp += 12;
+ assert(static_cast<unsigned>(m1) == static_cast<unsigned>(exp));
+// assert(off.count() == static_cast<unsigned>(exp));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..749635f813d2
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/plus.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+// constexpr month operator+(const month& x, const months& y) noexcept;
+// Returns: month(int{x} + y.count()).
+//
+// constexpr month operator+(const months& x, const month& y) noexcept;
+// Returns:
+// month{modulo(static_cast<long long>(int{x}) + (y.count() - 1), 12) + 1}
+// where modulo(n, 12) computes the remainder of n divided by 12 using Euclidean division.
+// [Note: Given a divisor of 12, Euclidean division truncates towards negative infinity
+// and always produces a remainder in the range of [0, 11].
+// Assuming no overflow in the signed summation, this operation results in a month
+// holding a value in the range [1, 12] even if !x.ok(). —end note]
+// [Example: February + months{11} == January. —end example]
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename M, typename Ms>
+constexpr bool testConstexpr()
+{
+ M m{1};
+ Ms offset{4};
+ if (m + offset != M{5}) return false;
+ if (offset + m != M{5}) return false;
+// Check the example
+ if (M{2} + Ms{11} != M{1}) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<month>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<month>());
+
+ ASSERT_SAME_TYPE(month, decltype(std::declval<month>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(month, decltype(std::declval<months>() + std::declval<month>() ));
+
+ static_assert(testConstexpr<month, months>(), "");
+
+ month my{2};
+ for (unsigned i = 0; i <= 15; ++i)
+ {
+ month m1 = my + months{i};
+ month m2 = months{i} + my;
+ assert(m1 == m2);
+ unsigned exp = i + 2;
+ while (exp > 12)
+ exp -= 12;
+ assert(static_cast<unsigned>(m1) == exp);
+ assert(static_cast<unsigned>(m2) == exp);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..abc2c1edc9bb
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class month;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const month& m);
+//
+// Effects: If m.ok() == true inserts format(os.getloc(), fmt, m) where fmt is "%b" widened to charT.
+// Otherwise inserts int{m} << " is not a valid month".
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const month& m);
+//
+// Effects: Streams m into os using the format specified by the NTCTS fmt.
+// fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// month& m, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the month m using the format flags
+// given in the NTCTS fmt as specified in 25.12. If the parse fails to decode a valid month,
+// is.setstate(ios_- base::failbit) shall be called and m shall not be modified.
+// If %Z is used and successfully parsed, that value will be assigned to *abbrev if
+// abbrev is non-null. If %z (or a modified variant) is used and successfully parsed,
+// that value will be assigned to *offset if offset is non-null.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ std::cout << month{1};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.month/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/types.pass.cpp
new file mode 100644
index 000000000000..af7532c7b713
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.month/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+
+ static_assert(std::is_trivially_copyable_v<month>, "");
+ static_assert(std::is_standard_layout_v<month>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ctor.pass.cpp
new file mode 100644
index 000000000000..445b86dde27c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ctor.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+// month_weekday represents the nth weekday of a month, of an as yet unspecified year.
+
+// constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept;
+// Effects: Constructs an object of type month_weekday by initializing m_ with m, and wdi_ with wdi.
+//
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ ASSERT_NOEXCEPT(month_weekday{month{1}, weekday_indexed{weekday{}, 1}});
+
+ constexpr month_weekday md0{month{}, weekday_indexed{}};
+ static_assert( md0.month() == month{}, "");
+ static_assert( md0.weekday_indexed() == weekday_indexed{}, "");
+ static_assert(!md0.ok(), "");
+
+ constexpr month_weekday md1{std::chrono::January, weekday_indexed{std::chrono::Friday, 4}};
+ static_assert( md1.month() == std::chrono::January, "");
+ static_assert( md1.weekday_indexed() == weekday_indexed{std::chrono::Friday, 4}, "");
+ static_assert( md1.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/month.pass.cpp
new file mode 100644
index 000000000000..f915b6deb4d7
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/month.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Sunday = std::chrono::Sunday;
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const month_weekday>().month()));
+
+ static_assert( month_weekday{}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_weekday md(month{i}, weekday_indexed{Sunday, 1});
+ assert( static_cast<unsigned>(md.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ok.pass.cpp
new file mode 100644
index 000000000000..11d9e28766ef
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ok.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && wdi_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Sunday = std::chrono::Sunday;
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const month_weekday>().ok()));
+
+ static_assert(!month_weekday{month{}, weekday_indexed{}}.ok(), "");
+ static_assert( month_weekday{std::chrono::May, weekday_indexed{Sunday, 2}}.ok(), "");
+
+ assert(!(month_weekday(std::chrono::April, weekday_indexed{Sunday, 0}).ok()));
+ assert( (month_weekday{std::chrono::March, weekday_indexed{Sunday, 1}}.ok()));
+
+ for (unsigned i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ month_weekday mwd{month{i}, weekday_indexed{Sunday, j}};
+ assert(mwd.ok() == (j >= 1 && j <= 5));
+ }
+
+// If the month is not ok, all the weekday_indexed are bad
+ for (unsigned i = 1; i <= 10; ++i)
+ assert(!(month_weekday{month{13}, weekday_indexed{Sunday, i}}.ok()));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/weekday_indexed.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/weekday_indexed.pass.cpp
new file mode 100644
index 000000000000..3eb67259c787
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/weekday_indexed.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+// constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
+// Returns: wdi_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Sunday = std::chrono::Sunday;
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday>().weekday_indexed());
+ ASSERT_SAME_TYPE(weekday_indexed, decltype(std::declval<const month_weekday>().weekday_indexed()));
+
+ static_assert( month_weekday{month{}, weekday_indexed{}}.weekday_indexed() == weekday_indexed{}, "");
+
+ for (unsigned i = 1; i <= 10; ++i)
+ {
+ month_weekday md(std::chrono::March, weekday_indexed{Sunday, i});
+ assert( static_cast<unsigned>(md.weekday_indexed().weekday() == Sunday));
+ assert( static_cast<unsigned>(md.weekday_indexed().index() == i));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..21779843a78f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+// constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
+// Returns: x.month() == y.month() && x.day() == y.day().
+//
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using weekday = std::chrono::weekday;
+
+ constexpr weekday Sunday = std::chrono::Sunday;
+ constexpr weekday Monday = std::chrono::Monday;
+
+ AssertComparisons2AreNoexcept<month_weekday>();
+ AssertComparisons2ReturnBool<month_weekday>();
+
+ static_assert( testComparisons2(
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 1}},
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 1}},
+ true), "");
+
+ static_assert( testComparisons2(
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 1}},
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 2}},
+ false), "");
+
+ static_assert( testComparisons2(
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 1}},
+ month_weekday{std::chrono::February, weekday_indexed{Sunday, 1}},
+ false), "");
+
+ static_assert( testComparisons2(
+ month_weekday{std::chrono::January, weekday_indexed{Monday, 1}},
+ month_weekday{std::chrono::January, weekday_indexed{Sunday, 2}},
+ false), "");
+
+ static_assert( testComparisons2(
+ month_weekday{std::chrono::January, weekday_indexed{Monday, 1}},
+ month_weekday{std::chrono::February, weekday_indexed{Sunday, 1}},
+ false), "");
+
+// same day, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons2(
+ month_weekday{month{i}, weekday_indexed{Sunday, 1}},
+ month_weekday{month{j}, weekday_indexed{Sunday, 1}},
+ i == j)));
+
+// same month, different weeks
+ for (unsigned i = 1; i < 5; ++i)
+ for (unsigned j = 1; j < 5; ++j)
+ assert((testComparisons2(
+ month_weekday{month{2}, weekday_indexed{Sunday, i}},
+ month_weekday{month{2}, weekday_indexed{Sunday, j}},
+ i == j)));
+
+// same month, different days
+ for (unsigned i = 0; i < 6; ++i)
+ for (unsigned j = 0; j < 6; ++j)
+ assert((testComparisons2(
+ month_weekday{month{2}, weekday_indexed{weekday{i}, 2}},
+ month_weekday{month{2}, weekday_indexed{weekday{j}, 2}},
+ i == j)));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..3858731f5933
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class month_weekday;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);
+//
+// Returns: os << mwd.month() << '/' << mwd.weekday_indexed().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using weekday = std::chrono::weekday;
+
+ std::cout << month_weekday{month{1}, weekday_indexed{weekday{3}, 3}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwd/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwd/types.pass.cpp
new file mode 100644
index 000000000000..86479d8caae4
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwd/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+
+ static_assert(std::is_trivially_copyable_v<month_weekday>, "");
+ static_assert(std::is_standard_layout_v<month_weekday>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ctor.pass.cpp
new file mode 100644
index 000000000000..2dd64eb80b6c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ctor.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr month_weekday_last(const chrono::month& m,
+// const chrono::weekday_last& wdl) noexcept;
+//
+// Effects: Constructs an object of type month_weekday_last by
+// initializing m_ with m, and wdl_ with wdl.
+//
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::weekday_last weekday_last() const noexcept;
+// constexpr bool ok() const noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT(month_weekday_last{January, weekday_last{Tuesday}});
+
+// bad month
+ constexpr month_weekday_last mwdl1{month{}, weekday_last{Tuesday}};
+ static_assert( mwdl1.month() == month{}, "");
+ static_assert( mwdl1.weekday_last() == weekday_last{Tuesday}, "");
+ static_assert(!mwdl1.ok(), "");
+
+// bad weekday_last
+ constexpr month_weekday_last mwdl2{January, weekday_last{weekday{16}}};
+ static_assert( mwdl2.month() == January, "");
+ static_assert( mwdl2.weekday_last() == weekday_last{weekday{16}}, "");
+ static_assert(!mwdl2.ok(), "");
+
+// Good month and weekday_last
+ constexpr month_weekday_last mwdl3{January, weekday_last{weekday{4}}};
+ static_assert( mwdl3.month() == January, "");
+ static_assert( mwdl3.weekday_last() == weekday_last{weekday{4}}, "");
+ static_assert( mwdl3.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/month.pass.cpp
new file mode 100644
index 000000000000..155e030ff13a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/month.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: m_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday_last>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const month_weekday_last>().month()));
+
+ static_assert( month_weekday_last{month{}, weekday_last{Tuesday}}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_weekday_last mdl(month{i}, weekday_last{Tuesday});
+ assert( static_cast<unsigned>(mdl.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ok.pass.cpp
new file mode 100644
index 000000000000..b464fec33e5a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ok.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && wdl_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr weekday_last lastTuesday = weekday_last{Tuesday};
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday_last>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const month_weekday_last>().ok()));
+
+ static_assert(!month_weekday_last{month{}, lastTuesday}.ok(), ""); // Bad month
+ static_assert(!month_weekday_last{January, weekday_last{weekday{12}}}.ok(), ""); // Bad month
+ static_assert( month_weekday_last{January, lastTuesday}.ok(), ""); // Both OK
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ month_weekday_last mwdl{month{i}, lastTuesday};
+ assert( mwdl.ok() == month{i}.ok());
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ month_weekday_last mwdl{January, weekday_last{weekday{i}}};
+ assert( mwdl.ok() == weekday_last{weekday{i}}.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/weekday_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/weekday_last.pass.cpp
new file mode 100644
index 000000000000..1a687d962dcf
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/weekday_last.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr chrono::weekday_last weekday_last() const noexcept;
+// Returns: wdl_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr weekday_last lastTuesday = weekday_last{Tuesday};
+
+ ASSERT_NOEXCEPT( std::declval<const month_weekday_last>().weekday_last());
+ ASSERT_SAME_TYPE(weekday_last, decltype(std::declval<const month_weekday_last>().weekday_last()));
+
+ static_assert( month_weekday_last{month{}, lastTuesday}.weekday_last() == lastTuesday, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ month_weekday_last mdl(January, weekday_last{weekday{i}});
+ assert( static_cast<unsigned>(mdl.weekday_last().weekday()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..b3cd5ec2b23a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
+// Returns: x.month() == y.month()
+//
+// constexpr bool operator< (const month_weekday_last& x, const month_weekday_last& y) noexcept;
+// Returns: x.month() < y.month()
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using weekday_last = std::chrono::weekday_last;
+ using weekday = std::chrono::weekday;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr weekday Wednesday = std::chrono::Wednesday;
+
+ AssertComparisons2AreNoexcept<month_weekday_last>();
+ AssertComparisons2ReturnBool<month_weekday_last>();
+
+ static_assert( testComparisons2(
+ month_weekday_last{std::chrono::January, weekday_last{Tuesday}},
+ month_weekday_last{std::chrono::January, weekday_last{Tuesday}},
+ true), "");
+
+ static_assert( testComparisons2(
+ month_weekday_last{std::chrono::January, weekday_last{Tuesday}},
+ month_weekday_last{std::chrono::January, weekday_last{Wednesday}},
+ false), "");
+
+// vary the months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons2(
+ month_weekday_last{month{i}, weekday_last{Tuesday}},
+ month_weekday_last{month{j}, weekday_last{Tuesday}},
+ i == j)));
+
+// vary the weekday
+ for (unsigned i = 0; i < 6; ++i)
+ for (unsigned j = 0; j < 6; ++j)
+ assert((testComparisons2(
+ month_weekday_last{January, weekday_last{weekday{i}}},
+ month_weekday_last{January, weekday_last{weekday{j}}},
+ i == j)));
+
+// both different
+ assert((testComparisons2(
+ month_weekday_last{month{1}, weekday_last{weekday{1}}},
+ month_weekday_last{month{2}, weekday_last{weekday{2}}},
+ false)));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..4e06812e00fc
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class month_weekday_last;
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mdl);
+//
+// Returns: os << mdl.month() << "/last".
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday_last = std::chrono::month_weekday_last;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ std::cout << month_weekday_last{month{1}, weekday_last{weekday{3}}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.mwdlast/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mwdlast/types.pass.cpp
new file mode 100644
index 000000000000..43982f4b4f3f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.mwdlast/types.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// class month_weekday_last;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ static_assert(std::is_trivially_copyable_v<month_weekday_last>, "");
+ static_assert(std::is_standard_layout_v<month_weekday_last>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/month_day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/month_day.pass.cpp
new file mode 100644
index 000000000000..146a0f180efb
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/month_day.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day;
+
+// constexpr month_day
+// operator/(const month& m, const day& d) noexcept;
+// Returns: {m, d}.
+//
+// constexpr month_day
+// operator/(const day& d, const month& m) noexcept;
+// Returns: m / d.
+
+// constexpr month_day
+// operator/(const month& m, int d) noexcept;
+// Returns: m / day(d).
+//
+// constexpr month_day
+// operator/(int m, const day& d) noexcept;
+// Returns: month(m) / d.
+//
+// constexpr month_day
+// operator/(const day& d, int m) noexcept;
+// Returns: month(m) / d.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month_day = std::chrono::month_day;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+
+ constexpr month February = std::chrono::February;
+
+ { // operator/(const month& m, const day& d) (and switched)
+ ASSERT_NOEXCEPT ( February/day{1});
+ ASSERT_SAME_TYPE(month_day, decltype(February/day{1}));
+ ASSERT_NOEXCEPT ( day{1}/February);
+ ASSERT_SAME_TYPE(month_day, decltype(day{1}/February));
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 30; ++j)
+ {
+ month m(i);
+ day d{j};
+ month_day md1 = m/d;
+ month_day md2 = d/m;
+ assert(md1.month() == m);
+ assert(md1.day() == d);
+ assert(md2.month() == m);
+ assert(md2.day() == d);
+ assert(md1 == md2);
+ }
+ }
+
+
+ { // operator/(const month& m, int d) (NOT switched)
+ ASSERT_NOEXCEPT ( February/2);
+ ASSERT_SAME_TYPE(month_day, decltype(February/2));
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 30; ++j)
+ {
+ month m(i);
+ day d(j);
+ month_day md1 = m/j;
+ assert(md1.month() == m);
+ assert(md1.day() == d);
+ }
+ }
+
+
+ { // operator/(const day& d, int m) (and switched)
+ ASSERT_NOEXCEPT ( day{2}/2);
+ ASSERT_SAME_TYPE(month_day, decltype(day{2}/2));
+ ASSERT_NOEXCEPT ( 2/day{2});
+ ASSERT_SAME_TYPE(month_day, decltype(2/day{2}));
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 30; ++j)
+ {
+ month m(i);
+ day d(j);
+ month_day md1 = d/i;
+ month_day md2 = i/d;
+ assert(md1.month() == m);
+ assert(md1.day() == d);
+ assert(md2.month() == m);
+ assert(md2.day() == d);
+ assert(md1 == md2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/month_day_last.pass.cpp
new file mode 100644
index 000000000000..f3f39c0dcc9d
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/month_day_last.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_day_last;
+
+// constexpr month_day_last
+// operator/(const month& m, last_spec) noexcept;
+// Returns: month_day_last{m}.
+//
+// constexpr month_day_last
+// operator/(int m, last_spec) noexcept;
+// Returns: month(m) / last.
+//
+// constexpr month_day_last
+// operator/(last_spec, const month& m) noexcept;
+// Returns: m / last.
+//
+// constexpr month_day_last
+// operator/(last_spec, int m) noexcept;
+// Returns: month(m) / last.
+//
+//
+// [Note: A month_day_last object can be constructed using the expression m/last or last/m,
+// where m is an expression of type month. — end note]
+// [Example:
+// constexpr auto mdl = February/last; // mdl is the last day of February of an as yet unspecified year
+// static_assert(mdl.month() == February);
+// --end example]
+
+
+
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ constexpr month February = std::chrono::February;
+ constexpr std::chrono::last_spec last = std::chrono::last;
+
+ ASSERT_SAME_TYPE(month_day_last, decltype(last/February));
+ ASSERT_SAME_TYPE(month_day_last, decltype(February/last));
+
+// Run the example
+ {
+ constexpr auto mdl = February/std::chrono::last;
+ static_assert(mdl.month() == February, "");
+ }
+
+ { // operator/(const month& m, last_spec) and switched
+ ASSERT_NOEXCEPT ( last/February);
+ ASSERT_SAME_TYPE(month_day_last, decltype(last/February));
+ ASSERT_NOEXCEPT ( February/last);
+ ASSERT_SAME_TYPE(month_day_last, decltype(February/last));
+
+ static_assert((last/February).month() == February, "");
+ static_assert((February/last).month() == February, "");
+
+ for (unsigned i = 1; i < 12; ++i)
+ {
+ month m{i};
+ month_day_last mdl1 = last/m;
+ month_day_last mdl2 = m/last;
+ assert(mdl1.month() == m);
+ assert(mdl2.month() == m);
+ assert(mdl1 == mdl2);
+ }
+ }
+
+ { // operator/(int, last_spec) and switched
+ ASSERT_NOEXCEPT ( last/2);
+ ASSERT_SAME_TYPE(month_day_last, decltype(last/2));
+ ASSERT_NOEXCEPT ( 2/last);
+ ASSERT_SAME_TYPE(month_day_last, decltype(2/last));
+
+ static_assert((last/2).month() == February, "");
+ static_assert((2/last).month() == February, "");
+
+ for (unsigned i = 1; i < 12; ++i)
+ {
+ month m{i};
+ month_day_last mdl1 = last/i;
+ month_day_last mdl2 = i/last;
+ assert(mdl1.month() == m);
+ assert(mdl2.month() == m);
+ assert(mdl1 == mdl2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/month_weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/month_weekday.pass.cpp
new file mode 100644
index 000000000000..54b494268aa8
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/month_weekday.pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday;
+
+// constexpr month_weekday
+// operator/(const month& m, const weekday_indexed& wdi) noexcept;
+// Returns: {m, wdi}.
+//
+// constexpr month_weekday
+// operator/(int m, const weekday_indexed& wdi) noexcept;
+// Returns: month(m) / wdi.
+//
+// constexpr month_weekday
+// operator/(const weekday_indexed& wdi, const month& m) noexcept;
+// Returns: m / wdi. constexpr month_weekday
+//
+// constexpr month_weekday
+// operator/(const weekday_indexed& wdi, int m) noexcept;
+// Returns: month(m) / wdi.
+
+
+//
+// [Example:
+// constexpr auto mwd = February/Tuesday[3]; // mwd is the third Tuesday of February of an as yet unspecified year
+// static_assert(mwd.month() == February);
+// static_assert(mwd.weekday_indexed() == Tuesday[3]);
+// —end example]
+
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month February = std::chrono::February;
+
+ { // operator/(const month& m, const weekday_indexed& wdi) (and switched)
+ ASSERT_NOEXCEPT (February/Tuesday[2]);
+ ASSERT_SAME_TYPE(month_weekday, decltype(February/Tuesday[2]));
+ ASSERT_NOEXCEPT (Tuesday[2]/February);
+ ASSERT_SAME_TYPE(month_weekday, decltype(Tuesday[2]/February));
+
+ // Run the example
+ {
+ constexpr month_weekday wdi = February/Tuesday[3];
+ static_assert(wdi.month() == February, "");
+ static_assert(wdi.weekday_indexed() == Tuesday[3], "");
+ }
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ for (unsigned k = 1; k <= 5; ++k)
+ {
+ month m(i);
+ weekday_indexed wdi = weekday{j}[k];
+ month_weekday mwd1 = m/wdi;
+ month_weekday mwd2 = wdi/m;
+ assert(mwd1.month() == m);
+ assert(mwd1.weekday_indexed() == wdi);
+ assert(mwd2.month() == m);
+ assert(mwd2.weekday_indexed() == wdi);
+ assert(mwd1 == mwd2);
+ }
+ }
+
+
+ { // operator/(int m, const weekday_indexed& wdi) (and switched)
+ ASSERT_NOEXCEPT (2/Tuesday[2]);
+ ASSERT_SAME_TYPE(month_weekday, decltype(2/Tuesday[2]));
+ ASSERT_NOEXCEPT (Tuesday[2]/2);
+ ASSERT_SAME_TYPE(month_weekday, decltype(Tuesday[2]/2));
+
+ // Run the example
+ {
+ constexpr month_weekday wdi = 2/Tuesday[3];
+ static_assert(wdi.month() == February, "");
+ static_assert(wdi.weekday_indexed() == Tuesday[3], "");
+ }
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ for (unsigned k = 1; k <= 5; ++k)
+ {
+ weekday_indexed wdi = weekday{j}[k];
+ month_weekday mwd1 = i/wdi;
+ month_weekday mwd2 = wdi/i;
+ assert(mwd1.month() == month(i));
+ assert(mwd1.weekday_indexed() == wdi);
+ assert(mwd2.month() == month(i));
+ assert(mwd2.weekday_indexed() == wdi);
+ assert(mwd1 == mwd2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/month_weekday_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/month_weekday_last.pass.cpp
new file mode 100644
index 000000000000..516e0f182f48
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/month_weekday_last.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class month_weekday_last;
+
+// constexpr month_weekday_last
+// operator/(const month& m, const weekday_last& wdl) noexcept;
+// Returns: {m, wdl}.
+//
+// constexpr month_weekday_last
+// operator/(int m, const weekday_last& wdl) noexcept;
+// Returns: month(m) / wdl.
+//
+// constexpr month_weekday_last
+// operator/(const weekday_last& wdl, const month& m) noexcept;
+// Returns: m / wdl.
+//
+// constexpr month_weekday_last
+// operator/(const weekday_last& wdl, int m) noexcept;
+// Returns: month(m) / wdl.
+
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month_weekday = std::chrono::month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month February = std::chrono::February;
+ constexpr std::chrono::last_spec last = std::chrono::last;
+
+ { // operator/(const month& m, const weekday_last& wdi) (and switched)
+ ASSERT_NOEXCEPT (February/Tuesday[last]);
+ ASSERT_SAME_TYPE(month_weekday_last, decltype(February/Tuesday[last]));
+ ASSERT_NOEXCEPT (Tuesday[last]/February);
+ ASSERT_SAME_TYPE(month_weekday_last, decltype(Tuesday[last]/February));
+
+ // Run the example
+ {
+ constexpr month_weekday_last wdi = February/Tuesday[last];
+ static_assert(wdi.month() == February, "");
+ static_assert(wdi.weekday_last() == Tuesday[last], "");
+ }
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ month m(i);
+ weekday_last wdi = weekday{j}[last];
+ month_weekday_last mwd1 = m/wdi;
+ month_weekday_last mwd2 = wdi/m;
+ assert(mwd1.month() == m);
+ assert(mwd1.weekday_last() == wdi);
+ assert(mwd2.month() == m);
+ assert(mwd2.weekday_last() == wdi);
+ assert(mwd1 == mwd2);
+ }
+ }
+
+
+ { // operator/(int m, const weekday_last& wdi) (and switched)
+ ASSERT_NOEXCEPT (2/Tuesday[2]);
+ ASSERT_SAME_TYPE(month_weekday_last, decltype(2/Tuesday[last]));
+ ASSERT_NOEXCEPT (Tuesday[2]/2);
+ ASSERT_SAME_TYPE(month_weekday_last, decltype(Tuesday[last]/2));
+
+ // Run the example
+ {
+ constexpr month_weekday wdi = 2/Tuesday[3];
+ static_assert(wdi.month() == February, "");
+ static_assert(wdi.weekday_indexed() == Tuesday[3], "");
+ }
+
+ for (int i = 1; i <= 12; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ weekday_last wdi = weekday{j}[last];
+ month_weekday_last mwd1 = i/wdi;
+ month_weekday_last mwd2 = wdi/i;
+ assert(mwd1.month() == month(i));
+ assert(mwd1.weekday_last() == wdi);
+ assert(mwd2.month() == month(i));
+ assert(mwd2.weekday_last() == wdi);
+ assert(mwd1 == mwd2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/year_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/year_month.pass.cpp
new file mode 100644
index 000000000000..62e1c3acefed
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/year_month.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr year_month operator/(const year& y, const month& m) noexcept;
+// Returns: {y, m}.
+//
+// constexpr year_month operator/(const year& y, int m) noexcept;
+// Returns: y / month(m).
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using year = std::chrono::year;
+ using year_month = std::chrono::year_month;
+
+ constexpr month February = std::chrono::February;
+
+ { // operator/(const year& y, const month& m)
+ ASSERT_NOEXCEPT ( year{2018}/February);
+ ASSERT_SAME_TYPE(year_month, decltype(year{2018}/February));
+
+ static_assert((year{2018}/February).year() == year{2018}, "");
+ static_assert((year{2018}/February).month() == month{2}, "");
+ for (int i = 1000; i <= 1030; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ {
+ year_month ym = year{i}/month{j};
+ assert(static_cast<int>(ym.year()) == i);
+ assert(static_cast<unsigned>(ym.month()) == j);
+ }
+ }
+
+
+ { // operator/(const year& y, const int m)
+ ASSERT_NOEXCEPT ( year{2018}/4);
+ ASSERT_SAME_TYPE(year_month, decltype(year{2018}/4));
+
+ static_assert((year{2018}/2).year() == year{2018}, "");
+ static_assert((year{2018}/2).month() == month{2}, "");
+
+ for (int i = 1000; i <= 1030; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ {
+ year_month ym = year{i}/j;
+ assert(static_cast<int>(ym.year()) == i);
+ assert(static_cast<unsigned>(ym.month()) == j);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/year_month_day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/year_month_day.pass.cpp
new file mode 100644
index 000000000000..d2dfc1321fea
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/year_month_day.pass.cpp
@@ -0,0 +1,191 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day
+// operator/(const year_month& ym, const day& d) noexcept;
+// Returns: {ym.year(), ym.month(), d}.
+//
+// constexpr year_month_day
+// operator/(const year_month& ym, int d) noexcept;
+// Returns: ym / day(d).
+//
+// constexpr year_month_day
+// operator/(const year& y, const month_day& md) noexcept;
+// Returns: y / md.month() / md.day().
+//
+// constexpr year_month_day
+// operator/(int y, const month_day& md) noexcept;
+// Returns: year(y) / md.
+//
+// constexpr year_month_day
+// operator/(const month_day& md, const year& y) noexcept;
+// Returns: y / md.
+//
+// constexpr year_month_day
+// operator/(const month_day& md, int y) noexcept;
+// Returns: year(y) / md.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month = std::chrono::year_month;
+ using month_day = std::chrono::month_day;
+ using year_month_day = std::chrono::year_month_day;
+
+ constexpr month February = std::chrono::February;
+ constexpr year_month Feb2018{year{2018}, February};
+
+ { // operator/(const year_month& ym, const day& d)
+ ASSERT_NOEXCEPT ( Feb2018/day{2});
+ ASSERT_SAME_TYPE(year_month_day, decltype(Feb2018/day{2}));
+
+ static_assert((Feb2018/day{2}).month() == February, "");
+ static_assert((Feb2018/day{2}).day() == day{2}, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 28; ++k)
+ {
+ year y(i);
+ month m(j);
+ day d(k);
+ year_month ym(y, m);
+ year_month_day ymd = ym/d;
+ assert(ymd.year() == y);
+ assert(ymd.month() == m);
+ assert(ymd.day() == d);
+ }
+ }
+
+
+ { // operator/(const year_month& ym, int d)
+ ASSERT_NOEXCEPT ( Feb2018/2);
+ ASSERT_SAME_TYPE(year_month_day, decltype(Feb2018/2));
+
+ static_assert((Feb2018/2).month() == February, "");
+ static_assert((Feb2018/2).day() == day{2}, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 28; ++k)
+ {
+ year y(i);
+ month m(j);
+ day d(k);
+ year_month ym(y, m);
+ year_month_day ymd = ym/k;
+ assert(ymd.year() == y);
+ assert(ymd.month() == m);
+ assert(ymd.day() == d);
+ }
+ }
+
+
+ { // operator/(const year_month& ym, int d)
+ ASSERT_NOEXCEPT ( Feb2018/2);
+ ASSERT_SAME_TYPE(year_month_day, decltype(Feb2018/2));
+
+ static_assert((Feb2018/2).month() == February, "");
+ static_assert((Feb2018/2).day() == day{2}, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 28; ++k)
+ {
+ year y(i);
+ month m(j);
+ day d(k);
+ year_month ym(y, m);
+ year_month_day ymd = ym/k;
+ assert(ymd.year() == y);
+ assert(ymd.month() == m);
+ assert(ymd.day() == d);
+ }
+ }
+
+
+
+
+ { // operator/(const year& y, const month_day& md) (and switched)
+ ASSERT_NOEXCEPT ( year{2018}/month_day{February, day{2}});
+ ASSERT_SAME_TYPE(year_month_day, decltype(year{2018}/month_day{February, day{2}}));
+ ASSERT_NOEXCEPT ( month_day{February, day{2}}/year{2018});
+ ASSERT_SAME_TYPE(year_month_day, decltype(month_day{February, day{2}}/year{2018}));
+
+ static_assert((year{2018}/month_day{February, day{2}}).month() == February, "" );
+ static_assert((year{2018}/month_day{February, day{2}}).day() == day{2}, "" );
+ static_assert((month_day{February, day{2}}/year{2018}).month() == February, "" );
+ static_assert((month_day{February, day{2}}/year{2018}).day() == day{2}, "" );
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 28; ++k)
+ {
+ year y(i);
+ month m(j);
+ day d(k);
+ month_day md(m, d);
+ year_month_day ymd1 = y/md;
+ year_month_day ymd2 = md/y;
+ assert(ymd1.year() == y);
+ assert(ymd2.year() == y);
+ assert(ymd1.month() == m);
+ assert(ymd2.month() == m);
+ assert(ymd1.day() == d);
+ assert(ymd2.day() == d);
+ assert(ymd1 == ymd2);
+ }
+ }
+
+ { // operator/(const month_day& md, int y) (and switched)
+ ASSERT_NOEXCEPT ( 2018/month_day{February, day{2}});
+ ASSERT_SAME_TYPE(year_month_day, decltype(2018/month_day{February, day{2}}));
+ ASSERT_NOEXCEPT ( month_day{February, day{2}}/2018);
+ ASSERT_SAME_TYPE(year_month_day, decltype(month_day{February, day{2}}/2018));
+
+ static_assert((2018/month_day{February, day{2}}).month() == February, "" );
+ static_assert((2018/month_day{February, day{2}}).day() == day{2}, "" );
+ static_assert((month_day{February, day{2}}/2018).month() == February, "" );
+ static_assert((month_day{February, day{2}}/2018).day() == day{2}, "" );
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 28; ++k)
+ {
+ year y(i);
+ month m(j);
+ day d(k);
+ month_day md(m, d);
+ year_month_day ymd1 = i/md;
+ year_month_day ymd2 = md/i;
+ assert(ymd1.year() == y);
+ assert(ymd2.year() == y);
+ assert(ymd1.month() == m);
+ assert(ymd2.month() == m);
+ assert(ymd1.day() == d);
+ assert(ymd2.day() == d);
+ assert(ymd1 == ymd2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/year_month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/year_month_day_last.pass.cpp
new file mode 100644
index 000000000000..dc884638dd2c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/year_month_day_last.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last
+// operator/(const year_month& ym, last_spec) noexcept;
+// Returns: {ym.year(), month_day_last{ym.month()}}.
+
+
+// constexpr year_month_day_last
+// operator/(const year& y, const month_day_last& mdl) noexcept;
+// Returns: {y, mdl}.
+//
+// constexpr year_month_day_last
+// operator/(int y, const month_day_last& mdl) noexcept;
+// Returns: year(y) / mdl.
+//
+// constexpr year_month_day_last
+// operator/(const month_day_last& mdl, const year& y) noexcept;
+// Returns: y / mdl.
+//
+// constexpr year_month_day_last
+// operator/(const month_day_last& mdl, int y) noexcept;
+// Returns: year(y) / mdl.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using year_month = std::chrono::year_month;
+ using year = std::chrono::year;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ constexpr month February = std::chrono::February;
+ constexpr std::chrono::last_spec last = std::chrono::last;
+
+ { // operator/(const year_month& ym, last_spec)
+ constexpr year_month Feb2018{year{2018}, February};
+
+ ASSERT_NOEXCEPT ( Feb2018/last);
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(Feb2018/last));
+
+ static_assert((Feb2018/last).year() == year{2018}, "");
+ static_assert((Feb2018/last).month() == February, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ {
+ year y{i};
+ month m{j};
+ year_month_day_last ymdl = year_month{y,m}/last;
+ assert(ymdl.year() == y);
+ assert(ymdl.month() == m);
+ }
+ }
+
+
+ { // operator/(const year& y, const month_day_last& mdl) (and switched)
+ ASSERT_NOEXCEPT ( year{2018}/month_day_last{February});
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(year{2018}/month_day_last{February}));
+ ASSERT_NOEXCEPT ( month_day_last{February}/year{2018});
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(month_day_last{February}/year{2018}));
+
+ static_assert((year{2018}/month_day_last{February}).month() == February, "");
+ static_assert((year{2018}/month_day_last{February}).year() == year{2018}, "");
+ static_assert((month_day_last{February}/year{2018}).month() == February, "");
+ static_assert((month_day_last{February}/year{2018}).year() == year{2018}, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ {
+ year y{i};
+ month m{j};
+ year_month_day_last ymdl1 = y/month_day_last{m};
+ year_month_day_last ymdl2 = month_day_last{m}/y;
+ assert(ymdl1.month() == m);
+ assert(ymdl2.month() == m);
+ assert(ymdl2.year() == y);
+ assert(ymdl1.year() == y);
+ assert(ymdl1 == ymdl2);
+ }
+ }
+
+ { // operator/(int y, const month_day_last& mdl) (and switched)
+ ASSERT_NOEXCEPT ( 2018/month_day_last{February});
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(2018/month_day_last{February}));
+ ASSERT_NOEXCEPT ( month_day_last{February}/2018);
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(month_day_last{February}/2018));
+
+ static_assert((2018/month_day_last{February}).month() == February, "");
+ static_assert((2018/month_day_last{February}).year() == year{2018}, "");
+ static_assert((month_day_last{February}/2018).month() == February, "");
+ static_assert((month_day_last{February}/2018).year() == year{2018}, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ {
+ year y{i};
+ month m{j};
+ year_month_day_last ymdl1 = i/month_day_last{m};
+ year_month_day_last ymdl2 = month_day_last{m}/i;
+ assert(ymdl1.month() == m);
+ assert(ymdl2.month() == m);
+ assert(ymdl2.year() == y);
+ assert(ymdl1.year() == y);
+ assert(ymdl1 == ymdl2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday.pass.cpp
new file mode 100644
index 000000000000..56d88ca7c3a1
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday
+// operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
+// Returns: {ym.year(), ym.month(), wdi}.
+//
+// constexpr year_month_weekday
+// operator/(const year& y, const month_weekday& mwd) noexcept;
+// Returns: {y, mwd.month(), mwd.weekday_indexed()}.
+//
+// constexpr year_month_weekday
+// operator/(int y, const month_weekday& mwd) noexcept;
+// Returns: year(y) / mwd.
+//
+// constexpr year_month_weekday
+// operator/(const month_weekday& mwd, const year& y) noexcept;
+// Returns: y / mwd.
+//
+// constexpr year_month_weekday
+// operator/(const month_weekday& mwd, int y) noexcept;
+// Returns: year(y) / mwd.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using year_month = std::chrono::year_month;
+ using month_weekday = std::chrono::month_weekday;
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month February = std::chrono::February;
+
+
+ { // operator/(const year_month& ym, const weekday_indexed& wdi)
+ constexpr year_month Feb2018{year{2018}, February};
+
+ ASSERT_NOEXCEPT ( Feb2018/weekday_indexed{Tuesday, 2});
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(Feb2018/weekday_indexed{Tuesday, 2}));
+
+ static_assert((Feb2018/weekday_indexed{Tuesday, 2}).year() == year{2018}, "" );
+ static_assert((Feb2018/weekday_indexed{Tuesday, 2}).month() == February, "" );
+ static_assert((Feb2018/weekday_indexed{Tuesday, 2}).weekday() == Tuesday, "" );
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ for (unsigned l = 1; l <= 5; ++l)
+ {
+ year y(i);
+ month m(j);
+ weekday wd{k};
+ year_month_weekday ymd = year_month{y,m}/weekday_indexed{wd,l};
+ assert(ymd.year() == y);
+ assert(ymd.month() == m);
+ assert(ymd.weekday() == wd);
+ }
+ }
+
+ { // operator/(const year& y, const month_weekday& mwd) (and switched)
+ constexpr month_weekday Feb1stTues{February, weekday_indexed{Tuesday, 1}};
+ ASSERT_NOEXCEPT ( year{2018}/Feb1stTues);
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(year{2018}/Feb1stTues));
+ ASSERT_NOEXCEPT ( Feb1stTues/year{2018});
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(Feb1stTues/year{2018}));
+
+ static_assert((year{2018}/Feb1stTues).year() == year{2018}, "" );
+ static_assert((year{2018}/Feb1stTues).month() == February, "" );
+ static_assert((year{2018}/Feb1stTues).weekday() == Tuesday, "" );
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ for (unsigned l = 1; l <= 5; ++l)
+ {
+ year y(i);
+ month m(j);
+ weekday wd{k};
+ month_weekday mwd{m, weekday_indexed{weekday{k}, l}};
+ year_month_weekday ymd1 = y/mwd;
+ year_month_weekday ymd2 = mwd/y;
+ assert(ymd1.year() == y);
+ assert(ymd2.year() == y);
+ assert(ymd1.month() == m);
+ assert(ymd2.month() == m);
+ assert(ymd1.weekday() == wd);
+ assert(ymd2.weekday() == wd);
+ assert(ymd1 == ymd2);
+ }
+ }
+
+
+ { // operator/(int y, const month_weekday& mwd) (and switched)
+ constexpr month_weekday Feb1stTues{February, weekday_indexed{Tuesday, 1}};
+ ASSERT_NOEXCEPT ( 2018/Feb1stTues);
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(2018/Feb1stTues));
+ ASSERT_NOEXCEPT ( Feb1stTues/2018);
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(Feb1stTues/2018));
+
+ static_assert((2018/Feb1stTues).year() == year{2018}, "" );
+ static_assert((2018/Feb1stTues).month() == February, "" );
+ static_assert((2018/Feb1stTues).weekday() == Tuesday, "" );
+
+ for (int i = 1000; i < 1010; ++i)
+ for (int j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ for (unsigned l = 1; l <= 5; ++l)
+ {
+ year y(i);
+ month m(j);
+ weekday wd{k};
+ month_weekday mwd{m, weekday_indexed{weekday{k}, l}};
+ year_month_weekday ymd1 = i/mwd;
+ year_month_weekday ymd2 = mwd/i;
+ assert(ymd1.year() == y);
+ assert(ymd2.year() == y);
+ assert(ymd1.month() == m);
+ assert(ymd2.month() == m);
+ assert(ymd1.weekday() == wd);
+ assert(ymd2.weekday() == wd);
+ assert(ymd1 == ymd2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday_last.pass.cpp
new file mode 100644
index 000000000000..84ea86c227bb
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday_last.pass.cpp
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last
+// operator/(const year_month& ym, const weekday_last& wdl) noexcept;
+// Returns: {ym.year(), ym.month(), wdl}.
+//
+// constexpr year_month_weekday_last
+// operator/(const year& y, const month_weekday_last& mwdl) noexcept;
+// Returns: {y, mwdl.month(), mwdl.weekday_last()}.
+//
+// constexpr year_month_weekday_last
+// operator/(int y, const month_weekday_last& mwdl) noexcept;
+// Returns: year(y) / mwdl.
+//
+// constexpr year_month_weekday_last
+// operator/(const month_weekday_last& mwdl, const year& y) noexcept;
+// Returns: y / mwdl.
+//
+// constexpr year_month_weekday_last
+// operator/(const month_weekday_last& mwdl, int y) noexcept;
+// Returns: year(y) / mwdl.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year_month = std::chrono::year_month;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using month_weekday_last = std::chrono::month_weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month February = std::chrono::February;
+
+ { // operator/(const year_month& ym, const weekday_last& wdl) (and switched)
+ constexpr year_month Feb2018{year{2018}, February};
+
+ ASSERT_NOEXCEPT ( Feb2018/weekday_last{Tuesday});
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(Feb2018/weekday_last{Tuesday}));
+
+ static_assert((Feb2018/weekday_last{Tuesday}).year() == year{2018}, "");
+ static_assert((Feb2018/weekday_last{Tuesday}).month() == February, "");
+ static_assert((Feb2018/weekday_last{Tuesday}).weekday() == Tuesday, "");
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ {
+ year y{i};
+ month m{j};
+ weekday wd{k};
+ year_month_weekday_last ymwdl = year_month{y,m}/weekday_last{wd};
+ assert(ymwdl.year() == y);
+ assert(ymwdl.month() == m);
+ assert(ymwdl.weekday() == wd);
+ }
+ }
+
+
+ { // operator/(const year& y, const month_weekday_last& mwdl) (and switched)
+ constexpr month_weekday_last FebLastTues{February, weekday_last{Tuesday}};
+
+ ASSERT_NOEXCEPT ( year{2018}/FebLastTues);
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(year{2018}/FebLastTues));
+ ASSERT_NOEXCEPT ( FebLastTues/year{2018});
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(FebLastTues/year{2018}));
+
+
+ static_assert((year{2018}/FebLastTues).year() == year{2018}, "");
+ static_assert((year{2018}/FebLastTues).month() == February, "");
+ static_assert((year{2018}/FebLastTues).weekday() == Tuesday, "");
+ static_assert((FebLastTues/year{2018}).year() == year{2018}, "");
+ static_assert((FebLastTues/year{2018}).month() == February, "");
+ static_assert((FebLastTues/year{2018}).weekday() == Tuesday, "");
+
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ {
+ year y{i};
+ month m{j};
+ weekday wd{k};
+ year_month_weekday_last ymwdl1 = y/month_weekday_last{m, weekday_last{wd}};
+ year_month_weekday_last ymwdl2 = month_weekday_last{m, weekday_last{wd}}/y;
+ assert(ymwdl1.year() == y);
+ assert(ymwdl2.year() == y);
+ assert(ymwdl1.month() == m);
+ assert(ymwdl2.month() == m);
+ assert(ymwdl1.weekday() == wd);
+ assert(ymwdl2.weekday() == wd);
+ assert(ymwdl1 == ymwdl2);
+ }
+ }
+
+
+ { // operator/(int y, const month_weekday_last& mwdl) (and switched)
+ constexpr month_weekday_last FebLastTues{February, weekday_last{Tuesday}};
+
+ ASSERT_NOEXCEPT ( 2018/FebLastTues);
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(2018/FebLastTues));
+ ASSERT_NOEXCEPT ( FebLastTues/2018);
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(FebLastTues/2018));
+
+
+ static_assert((2018/FebLastTues).year() == year{2018}, "");
+ static_assert((2018/FebLastTues).month() == February, "");
+ static_assert((2018/FebLastTues).weekday() == Tuesday, "");
+ static_assert((FebLastTues/2018).year() == year{2018}, "");
+ static_assert((FebLastTues/2018).month() == February, "");
+ static_assert((FebLastTues/2018).weekday() == Tuesday, "");
+
+
+ for (int i = 1000; i < 1010; ++i)
+ for (unsigned j = 1; j <= 12; ++j)
+ for (unsigned k = 0; k <= 6; ++k)
+ {
+ year y{i};
+ month m{j};
+ weekday wd{k};
+ year_month_weekday_last ymwdl1 = i/month_weekday_last{m, weekday_last{wd}};
+ year_month_weekday_last ymwdl2 = month_weekday_last{m, weekday_last{wd}}/i;
+ assert(ymwdl1.year() == y);
+ assert(ymwdl2.year() == y);
+ assert(ymwdl1.month() == m);
+ assert(ymwdl2.month() == m);
+ assert(ymwdl1.weekday() == wd);
+ assert(ymwdl2.weekday() == wd);
+ assert(ymwdl1 == ymwdl2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ctor.pass.cpp
new file mode 100644
index 000000000000..7a9cfd2d61aa
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ctor.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+// weekday_indexed() = default;
+// constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept;
+//
+// Effects: Constructs an object of type weekday_indexed by initializing wd_ with wd and index_ with index.
+// The values held are unspecified if !wd.ok() or index is not in the range [1, 5].
+//
+// constexpr chrono::weekday weekday() const noexcept;
+// constexpr unsigned index() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ ASSERT_NOEXCEPT(weekday_indexed{});
+ ASSERT_NOEXCEPT(weekday_indexed(weekday{1}, 1));
+
+ constexpr weekday_indexed wdi0{};
+ static_assert( wdi0.weekday() == weekday{}, "");
+ static_assert( wdi0.index() == 0, "");
+ static_assert(!wdi0.ok(), "");
+
+ constexpr weekday_indexed wdi1{std::chrono::Sunday, 2};
+ static_assert( wdi1.weekday() == std::chrono::Sunday, "");
+ static_assert( wdi1.index() == 2, "");
+ static_assert( wdi1.ok(), "");
+
+ for (unsigned i = 1; i <= 5; ++i)
+ {
+ weekday_indexed wdi(std::chrono::Tuesday, i);
+ assert( wdi.weekday() == std::chrono::Tuesday);
+ assert( wdi.index() == i);
+ assert( wdi.ok());
+ }
+
+ for (unsigned i = 6; i <= 20; ++i)
+ {
+ weekday_indexed wdi(std::chrono::Tuesday, i);
+ assert(!wdi.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/index.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/index.pass.cpp
new file mode 100644
index 000000000000..5a29087f2c4c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/index.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+// constexpr unsigned index() const noexcept;
+// Returns: index_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday_indexed>().index());
+ ASSERT_SAME_TYPE(unsigned, decltype(std::declval<const weekday_indexed>().index()));
+
+ static_assert( weekday_indexed{}.index() == 0, "");
+
+ for (unsigned i = 1; i <= 5; ++i)
+ {
+ weekday_indexed wdi(weekday{2}, i);
+ assert( static_cast<unsigned>(wdi.index()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ok.pass.cpp
new file mode 100644
index 000000000000..e711426cd2f3
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ok.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+// constexpr bool ok() const noexcept;
+// Returns: wd_.ok() && 1 <= index_ && index_ <= 5
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday_indexed>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const weekday_indexed>().ok()));
+
+ static_assert(!weekday_indexed{}.ok(), "");
+ static_assert( weekday_indexed{std::chrono::Sunday, 2}.ok(), "");
+
+ assert(!(weekday_indexed(std::chrono::Tuesday, 0).ok()));
+ for (unsigned i = 1; i <= 5; ++i)
+ {
+ weekday_indexed wdi(std::chrono::Tuesday, i);
+ assert( wdi.ok());
+ }
+
+ for (unsigned i = 6; i <= 20; ++i)
+ {
+ weekday_indexed wdi(std::chrono::Tuesday, i);
+ assert(!wdi.ok());
+ }
+
+// Not a valid weekday
+ assert(!(weekday_indexed(weekday{9U}, 1).ok()));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/weekday.pass.cpp
new file mode 100644
index 000000000000..da975ffc4867
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/weekday.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+// constexpr chrono::weekday weekday() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday_indexed>().weekday());
+ ASSERT_SAME_TYPE(std::chrono::weekday, decltype(std::declval<const weekday_indexed>().weekday()));
+
+ static_assert( weekday_indexed{}.weekday() == weekday{}, "");
+ static_assert( weekday_indexed{std::chrono::Tuesday, 0}.weekday() == std::chrono::Tuesday, "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday_indexed wdi(weekday{i}, 2);
+ assert( static_cast<unsigned>(wdi.weekday()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..2381322fad33
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+// constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
+// Returns: x.weekday() == y.weekday() && x.index() == y.index().
+// constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
+// Returns: !(x == y)
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ AssertComparisons2AreNoexcept<weekday_indexed>();
+ AssertComparisons2ReturnBool<weekday_indexed>();
+
+ static_assert( (weekday_indexed{} == weekday_indexed{}), "");
+ static_assert(!(weekday_indexed{} != weekday_indexed{}), "");
+
+ static_assert(!(weekday_indexed{} == weekday_indexed{std::chrono::Tuesday, 1}), "");
+ static_assert( (weekday_indexed{} != weekday_indexed{std::chrono::Tuesday, 1}), "");
+
+// Some 'ok' values as well
+ static_assert( (weekday_indexed{weekday{1}, 2} == weekday_indexed{weekday{1}, 2}), "");
+ static_assert(!(weekday_indexed{weekday{1}, 2} != weekday_indexed{weekday{1}, 2}), "");
+
+ static_assert(!(weekday_indexed{weekday{1}, 2} == weekday_indexed{weekday{1}, 1}), "");
+ static_assert( (weekday_indexed{weekday{1}, 2} != weekday_indexed{weekday{1}, 1}), "");
+ static_assert(!(weekday_indexed{weekday{1}, 2} == weekday_indexed{weekday{2}, 2}), "");
+ static_assert( (weekday_indexed{weekday{1}, 2} != weekday_indexed{weekday{2}, 2}), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..0e5f77dd7e76
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class weekday_indexed;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);
+//
+// Effects: os << wdi.weekday() << '[' << wdi.index().
+// If wdi.index() is in the range [1, 5], appends with ']',
+// otherwise appends with " is not a valid index]".
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using weekday = std::chrono::weekday;
+
+ std::cout << weekday_indexed{weekday{3}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdidx/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdidx/types.pass.cpp
new file mode 100644
index 000000000000..a21ae0dc55d4
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdidx/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_indexed;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ static_assert(std::is_trivially_copyable_v<weekday_indexed>, "");
+ static_assert(std::is_standard_layout_v<weekday_indexed>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ctor.pass.cpp
new file mode 100644
index 000000000000..1ea5196ad99a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ctor.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_last;
+
+// explicit constexpr weekday_last(const chrono::weekday& wd) noexcept;
+//
+// Effects: Constructs an object of type weekday_last by initializing wd_ with wd.
+//
+// constexpr chrono::weekday weekday() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ ASSERT_NOEXCEPT(weekday_last{weekday{}});
+
+ constexpr weekday_last wdl0{weekday{}};
+ static_assert( wdl0.weekday() == weekday{}, "");
+ static_assert( wdl0.ok(), "");
+
+ constexpr weekday_last wdl1 {weekday{1}};
+ static_assert( wdl1.weekday() == weekday{1}, "");
+ static_assert( wdl1.ok(), "");
+
+ for (unsigned i = 0; i <= 255; ++i)
+ {
+ weekday_last wdl{weekday{i}};
+ assert(wdl.weekday() == weekday{i});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ok.pass.cpp
new file mode 100644
index 000000000000..4bd0f6c2c3fa
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ok.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_last;
+
+// constexpr bool ok() const noexcept;
+// Returns: wd_.ok()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday_last>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const weekday_last>().ok()));
+
+ static_assert( weekday_last{weekday{0}}.ok(), "");
+ static_assert( weekday_last{weekday{1}}.ok(), "");
+ static_assert(!weekday_last{weekday{7}}.ok(), "");
+
+ for (unsigned i = 0; i <= 255; ++i)
+ assert(weekday_last{weekday{i}}.ok() == weekday{i}.ok());
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/weekday.pass.cpp
new file mode 100644
index 000000000000..403ce0cf7b2c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/weekday.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_last;
+
+// constexpr chrono::weekday weekday() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday_last>().weekday());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<const weekday_last>().weekday()));
+
+ for (unsigned i = 0; i <= 255; ++i)
+ assert(weekday_last{weekday{i}}.weekday() == weekday{i});
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..59ab4da08a36
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_last;
+
+// constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
+// constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ AssertComparisons2AreNoexcept<weekday_last>();
+ AssertComparisons2ReturnBool<weekday_last>();
+
+ static_assert(testComparisons2Values<weekday_last>(weekday{0}, weekday{0}), "");
+ static_assert(testComparisons2Values<weekday_last>(weekday{0}, weekday{1}), "");
+
+// Some 'ok' values as well
+ static_assert(testComparisons2Values<weekday_last>(weekday{2}, weekday{2}), "");
+ static_assert(testComparisons2Values<weekday_last>(weekday{2}, weekday{3}), "");
+
+ for (unsigned i = 0; i < 6; ++i)
+ for (unsigned j = 0; j < 6; ++j)
+ assert(testComparisons2Values<weekday_last>(weekday{i}, weekday{j}));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..65d0eed4a49b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class weekday_last;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);
+//
+// Returns: os << wdl.weekday() << "[last]".
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday_last = std::chrono::weekday_last;
+ using weekday = std::chrono::weekday;
+
+ std::cout << weekday_last{weekday{3}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.wdlast/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.wdlast/types.pass.cpp
new file mode 100644
index 000000000000..f6c191329d54
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.wdlast/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday_last;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday_last = std::chrono::weekday_last;
+
+ static_assert(std::is_trivially_copyable_v<weekday_last>, "");
+ static_assert(std::is_standard_layout_v<weekday_last>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp
new file mode 100644
index 000000000000..23513823510c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.local_days.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday(const local_days& dp) noexcept;
+//
+// Effects: Constructs an object of type weekday by computing what day
+// of the week corresponds to the local_days dp, and representing
+// that day of the week in wd_
+//
+// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true,
+// ymd == year_month_day{sys_days{ymd}} is true.
+//
+// [Example:
+// If dp represents 1970-01-01, the constructed weekday represents Thursday by storing 4 in wd_.
+// —end example]
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+ using weekday = std::chrono::weekday;
+
+ ASSERT_NOEXCEPT(weekday{std::declval<local_days>()});
+
+ {
+ constexpr local_days sd{}; // 1-Jan-1970 was a Thursday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 4, "");
+ }
+
+ {
+ constexpr local_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 3, "");
+ }
+
+
+ {
+ constexpr local_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 2, "");
+ }
+
+ {
+ local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
+ weekday wd{sd};
+
+ assert( wd.ok());
+ assert(static_cast<unsigned>(wd) == 3);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.pass.cpp
new file mode 100644
index 000000000000..f6bfc2192875
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// weekday() = default;
+// explicit constexpr weekday(unsigned wd) noexcept;
+// constexpr weekday(const sys_days& dp) noexcept;
+// explicit constexpr weekday(const local_days& dp) noexcept;
+//
+// explicit constexpr operator unsigned() const noexcept;
+
+// Effects: Constructs an object of type weekday by initializing m_ with m.
+// The value held is unspecified if d is not in the range [0, 255].
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+
+ ASSERT_NOEXCEPT(weekday{});
+ ASSERT_NOEXCEPT(weekday(1));
+ ASSERT_NOEXCEPT(static_cast<unsigned>(weekday(1)));
+
+ constexpr weekday m0{};
+ static_assert(static_cast<unsigned>(m0) == 0, "");
+
+ constexpr weekday m1{1};
+ static_assert(static_cast<unsigned>(m1) == 1, "");
+
+ for (unsigned i = 0; i <= 255; ++i)
+ {
+ weekday m(i);
+ assert(static_cast<unsigned>(m) == i);
+ }
+
+// TODO - sys_days and local_days ctor tests
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp
new file mode 100644
index 000000000000..c49d05d3ae54
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ctor.sys_days.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday(const sys_days& dp) noexcept;
+//
+// Effects: Constructs an object of type weekday by computing what day
+// of the week corresponds to the sys_days dp, and representing
+// that day of the week in wd_
+//
+// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true,
+// ymd == year_month_day{sys_days{ymd}} is true.
+//
+// [Example:
+// If dp represents 1970-01-01, the constructed weekday represents Thursday by storing 4 in wd_.
+// —end example]
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+ using weekday = std::chrono::weekday;
+
+ ASSERT_NOEXCEPT(weekday{std::declval<sys_days>()});
+
+ {
+ constexpr sys_days sd{}; // 1-Jan-1970 was a Thursday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 4, "");
+ }
+
+ {
+ constexpr sys_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 3, "");
+ }
+
+
+ {
+ constexpr sys_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday
+ constexpr weekday wd{sd};
+
+ static_assert( wd.ok(), "");
+ static_assert(static_cast<unsigned>(wd) == 2, "");
+ }
+
+ {
+ sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
+ weekday wd{sd};
+
+ assert( wd.ok());
+ assert(static_cast<unsigned>(wd) == 3);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/decrement.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/decrement.pass.cpp
new file mode 100644
index 000000000000..74774b6a0dcc
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/decrement.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday& operator--() noexcept;
+// constexpr weekday operator--(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+template <typename WD>
+constexpr bool testConstexpr()
+{
+ WD wd{1};
+ if (static_cast<unsigned>(--wd) != 0) return false;
+ if (static_cast<unsigned>(wd--) != 0) return false;
+ if (static_cast<unsigned>(wd) != 6) return false;
+ return true;
+}
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ ASSERT_NOEXCEPT(--(std::declval<weekday&>()) );
+ ASSERT_NOEXCEPT( (std::declval<weekday&>())--);
+
+ ASSERT_SAME_TYPE(weekday , decltype( std::declval<weekday&>()--));
+ ASSERT_SAME_TYPE(weekday&, decltype(--std::declval<weekday&>() ));
+
+ static_assert(testConstexpr<weekday>(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday wd(i);
+ assert((static_cast<unsigned>(--wd) == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
+ assert((static_cast<unsigned>(wd--) == euclidian_subtraction<unsigned, 0, 6>(i, 1)));
+ assert((static_cast<unsigned>(wd) == euclidian_subtraction<unsigned, 0, 6>(i, 2)));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp
new file mode 100644
index 000000000000..945d97f49bae
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday& operator++() noexcept;
+// constexpr weekday operator++(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+template <typename WD>
+constexpr bool testConstexpr()
+{
+ WD wd{5};
+ if (static_cast<unsigned>(++wd) != 6) return false;
+ if (static_cast<unsigned>(wd++) != 6) return false;
+ if (static_cast<unsigned>(wd) != 0) return false;
+ return true;
+}
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ ASSERT_NOEXCEPT(++(std::declval<weekday&>()) );
+ ASSERT_NOEXCEPT( (std::declval<weekday&>())++);
+
+ ASSERT_SAME_TYPE(weekday , decltype( std::declval<weekday&>()++));
+ ASSERT_SAME_TYPE(weekday&, decltype(++std::declval<weekday&>() ));
+
+ static_assert(testConstexpr<weekday>(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday wd(i);
+ assert((static_cast<unsigned>(++wd) == euclidian_addition<unsigned, 0, 6>(i, 1)));
+ assert((static_cast<unsigned>(wd++) == euclidian_addition<unsigned, 0, 6>(i, 1)));
+ assert((static_cast<unsigned>(wd) == euclidian_addition<unsigned, 0, 6>(i, 2)));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ok.pass.cpp
new file mode 100644
index 000000000000..5b03b181cc0c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/ok.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr bool ok() const noexcept;
+// Returns: wd_ <= 6
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const weekday>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const weekday>().ok()));
+
+ static_assert( weekday{0}.ok(), "");
+ static_assert( weekday{1}.ok(), "");
+ static_assert(!weekday{7}.ok(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ assert(weekday{i}.ok());
+ for (unsigned i = 7; i <= 255; ++i)
+ assert(!weekday{i}.ok());
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/operator[].pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/operator[].pass.cpp
new file mode 100644
index 000000000000..1498d2748ecd
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/operator[].pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday_indexed operator[](unsigned index) const noexcept;
+// constexpr weekday_last operator[](last_spec) const noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using weekday_indexed = std::chrono::weekday_indexed;
+
+ constexpr weekday Sunday = std::chrono::Sunday;
+
+ ASSERT_NOEXCEPT( std::declval<weekday>()[1U]);
+ ASSERT_SAME_TYPE(weekday_indexed, decltype(std::declval<weekday>()[1U]));
+
+ ASSERT_NOEXCEPT( std::declval<weekday>()[std::chrono::last]);
+ ASSERT_SAME_TYPE(weekday_last, decltype(std::declval<weekday>()[std::chrono::last]));
+
+ static_assert(Sunday[2].weekday() == Sunday, "");
+ static_assert(Sunday[2].index () == 2, "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday wd(i);
+ weekday_last wdl = wd[std::chrono::last];
+ assert(wdl.weekday() == wd);
+ assert(wdl.ok());
+ }
+
+ for (unsigned i = 0; i <= 6; ++i)
+ for (unsigned j = 1; j <= 5; ++j)
+ {
+ weekday wd(i);
+ weekday_indexed wdi = wd[j];
+ assert(wdi.weekday() == wd);
+ assert(wdi.index() == j);
+ assert(wdi.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp
new file mode 100644
index 000000000000..27c14a55a4a9
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday& operator+=(const days& d) noexcept;
+// constexpr weekday& operator-=(const days& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+template <typename M, typename Ms>
+constexpr bool testConstexpr()
+{
+ M m1{1};
+ if (static_cast<unsigned>(m1 += Ms{ 1}) != 2) return false;
+ if (static_cast<unsigned>(m1 += Ms{ 2}) != 4) return false;
+ if (static_cast<unsigned>(m1 += Ms{ 4}) != 1) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 1}) != 0) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 2}) != 5) return false;
+ if (static_cast<unsigned>(m1 -= Ms{ 4}) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( std::declval<weekday&>() += std::declval<days&>());
+ ASSERT_SAME_TYPE(weekday&, decltype(std::declval<weekday&>() += std::declval<days&>()));
+
+ ASSERT_NOEXCEPT( std::declval<weekday&>() -= std::declval<days&>());
+ ASSERT_SAME_TYPE(weekday&, decltype(std::declval<weekday&>() -= std::declval<days&>()));
+
+ static_assert(testConstexpr<weekday, days>(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday wd(i);
+ assert((static_cast<unsigned>(wd += days{3}) == euclidian_addition<unsigned, 0, 6>(i, 3)));
+ assert((static_cast<unsigned>(wd) == euclidian_addition<unsigned, 0, 6>(i, 3)));
+ }
+
+ for (unsigned i = 0; i <= 6; ++i)
+ {
+ weekday wd(i);
+ assert((static_cast<unsigned>(wd -= days{4}) == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
+ assert((static_cast<unsigned>(wd) == euclidian_subtraction<unsigned, 0, 6>(i, 4)));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..0142feee8f60
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
+// constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+
+ AssertComparisons2AreNoexcept<weekday>();
+ AssertComparisons2ReturnBool<weekday>();
+
+ static_assert(testComparisons2Values<weekday>(0U ,0U), "");
+ static_assert(testComparisons2Values<weekday>(0U, 1U), "");
+
+// Some 'ok' values as well
+ static_assert(testComparisons2Values<weekday>(5U, 5U), "");
+ static_assert(testComparisons2Values<weekday>(5U, 2U), "");
+
+ for (unsigned i = 0; i < 6; ++i)
+ for (unsigned j = 0; j < 6; ++j)
+ assert(testComparisons2Values<weekday>(i, j));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/literals.pass.cpp
new file mode 100644
index 000000000000..16f9899d655a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/literals.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// 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};
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Sunday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Monday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Tuesday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Wednesday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Thursday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Friday));
+ ASSERT_SAME_TYPE(const std::chrono::weekday, decltype(std::chrono::Saturday));
+
+ static_assert( std::chrono::Sunday == std::chrono::weekday(0), "");
+ static_assert( std::chrono::Monday == std::chrono::weekday(1), "");
+ static_assert( std::chrono::Tuesday == std::chrono::weekday(2), "");
+ static_assert( std::chrono::Wednesday == std::chrono::weekday(3), "");
+ static_assert( std::chrono::Thursday == std::chrono::weekday(4), "");
+ static_assert( std::chrono::Friday == std::chrono::weekday(5), "");
+ static_assert( std::chrono::Saturday == std::chrono::weekday(6), "");
+
+ assert(std::chrono::Sunday == std::chrono::weekday(0));
+ assert(std::chrono::Monday == std::chrono::weekday(1));
+ assert(std::chrono::Tuesday == std::chrono::weekday(2));
+ assert(std::chrono::Wednesday == std::chrono::weekday(3));
+ assert(std::chrono::Thursday == std::chrono::weekday(4));
+ assert(std::chrono::Friday == std::chrono::weekday(5));
+ assert(std::chrono::Saturday == std::chrono::weekday(6));
+
+ assert(static_cast<unsigned>(std::chrono::Sunday) == 0);
+ assert(static_cast<unsigned>(std::chrono::Monday) == 1);
+ assert(static_cast<unsigned>(std::chrono::Tuesday) == 2);
+ assert(static_cast<unsigned>(std::chrono::Wednesday) == 3);
+ assert(static_cast<unsigned>(std::chrono::Thursday) == 4);
+ assert(static_cast<unsigned>(std::chrono::Friday) == 5);
+ assert(static_cast<unsigned>(std::chrono::Saturday) == 6);
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..ca126e9dcead
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday operator-(const weekday& x, const days& y) noexcept;
+// Returns: x + -y.
+//
+// constexpr days operator-(const weekday& x, const weekday& y) noexcept;
+// Returns: If x.ok() == true and y.ok() == true, returns a value d in the range
+// [days{0}, days{6}] satisfying y + d == x.
+// Otherwise the value returned is unspecified.
+// [Example: Sunday - Monday == days{6}. —end example]
+
+
+extern "C" int printf(const char *, ...);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+template <typename WD, typename Ds>
+constexpr bool testConstexpr()
+{
+ {
+ WD wd{5};
+ Ds offset{3};
+ if (wd - offset != WD{2}) return false;
+ if (wd - WD{2} != offset) return false;
+ }
+
+// Check the example
+ if (WD{0} - WD{1} != Ds{6}) return false;
+ return true;
+}
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( std::declval<weekday>() - std::declval<days>());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<weekday>() - std::declval<days>()));
+
+ ASSERT_NOEXCEPT( std::declval<weekday>() - std::declval<weekday>());
+ ASSERT_SAME_TYPE(days, decltype(std::declval<weekday>() - std::declval<weekday>()));
+
+ static_assert(testConstexpr<weekday, days>(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ weekday wd = weekday{i} - days{j};
+ assert(wd + days{j} == weekday{i});
+ assert((static_cast<unsigned>(wd) == euclidian_subtraction<unsigned, 0, 6>(i, j)));
+ }
+
+ for (unsigned i = 0; i <= 6; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ days d = weekday{j} - weekday{i};
+ assert(weekday{i} + d == weekday{j});
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..bb9145a6575b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/plus.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+// constexpr weekday operator+(const days& x, const weekday& y) noexcept;
+// Returns: weekday(int{x} + y.count()).
+//
+// constexpr weekday operator+(const weekday& x, const days& y) noexcept;
+// Returns:
+// weekday{modulo(static_cast<long long>(unsigned{x}) + y.count(), 7)}
+// where modulo(n, 7) computes the remainder of n divided by 7 using Euclidean division.
+// [Note: Given a divisor of 12, Euclidean division truncates towards negative infinity
+// and always produces a remainder in the range of [0, 6].
+// Assuming no overflow in the signed summation, this operation results in a weekday
+// holding a value in the range [0, 6] even if !x.ok(). —end note]
+// [Example: Monday + days{6} == Sunday. —end example]
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "../../euclidian.h"
+
+template <typename M, typename Ms>
+constexpr bool testConstexpr()
+{
+ M m{1};
+ Ms offset{4};
+ if (m + offset != M{5}) return false;
+ if (offset + m != M{5}) return false;
+// Check the example
+ if (M{1} + Ms{6} != M{0}) return false;
+ return true;
+}
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( std::declval<weekday>() + std::declval<days>());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<weekday>() + std::declval<days>()));
+
+ ASSERT_NOEXCEPT( std::declval<days>() + std::declval<weekday>());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<days>() + std::declval<weekday>()));
+
+ static_assert(testConstexpr<weekday, days>(), "");
+
+ for (unsigned i = 0; i <= 6; ++i)
+ for (unsigned j = 0; j <= 6; ++j)
+ {
+ weekday wd1 = weekday{i} + days{j};
+ weekday wd2 = days{j} + weekday{i};
+ assert(wd1 == wd2);
+ assert((static_cast<unsigned>(wd1) == euclidian_addition<unsigned, 0, 6>(i, j)));
+ assert((static_cast<unsigned>(wd2) == euclidian_addition<unsigned, 0, 6>(i, j)));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..cf28397a3df0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class weekday;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const weekday& wd);
+//
+// Effects: If wd.ok() == true inserts format(os.getloc(), fmt, wd) where fmt is "%a" widened to charT.
+// Otherwise inserts unsigned{wd} << " is not a valid weekday".
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const weekday& wd);
+//
+// Effects: Streams wd into os using the format specified by the NTCTS fmt.
+// fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// weekday& wd, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the weekday wd using
+// the format flags given in the NTCTS fmt as specified in 25.12.
+// If the parse fails to decode a valid weekday, is.setstate(ios_- base::failbit)
+// shall be called and wd shall not be modified.
+// If %Z is used and successfully parsed, that value will be assigned
+// to *abbrev if abbrev is non-null.
+// If %z (or a modified variant) is used and successfully parsed,
+// that value will be assigned to *offset if offset is non-null.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+
+ std::cout << weekday{3};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.weekday/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/types.pass.cpp
new file mode 100644
index 000000000000..0a3a8940618b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.weekday/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class weekday;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using weekday = std::chrono::weekday;
+
+ static_assert(std::is_trivially_copyable_v<weekday>, "");
+ static_assert(std::is_standard_layout_v<weekday>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ctor.pass.cpp
new file mode 100644
index 000000000000..904e722dbc85
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ctor.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// year() = default;
+// explicit constexpr year(int m) noexcept;
+// explicit constexpr operator int() const noexcept;
+
+// Effects: Constructs an object of type year by initializing y_ with y.
+// The value held is unspecified if d is not in the range [0, 255].
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+
+ ASSERT_NOEXCEPT(year{});
+ ASSERT_NOEXCEPT(year(0U));
+ ASSERT_NOEXCEPT(static_cast<int>(year(0U)));
+
+ constexpr year y0{};
+ static_assert(static_cast<int>(y0) == 0, "");
+
+ constexpr year y1{1};
+ static_assert(static_cast<int>(y1) == 1, "");
+
+ for (int i = 0; i <= 2550; i += 7)
+ {
+ year year(i);
+ assert(static_cast<int>(year) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/decrement.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/decrement.pass.cpp
new file mode 100644
index 000000000000..810b28d9b2e9
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/decrement.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year& operator--() noexcept;
+// constexpr year operator--(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y>
+constexpr bool testConstexpr()
+{
+ Y y1{10};
+ if (static_cast<int>(--y1) != 9) return false;
+ if (static_cast<int>(y1--) != 9) return false;
+ if (static_cast<int>(y1) != 8) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ ASSERT_NOEXCEPT(--(std::declval<year&>()) );
+ ASSERT_NOEXCEPT( (std::declval<year&>())--);
+
+ ASSERT_SAME_TYPE(year , decltype( std::declval<year&>()--));
+ ASSERT_SAME_TYPE(year&, decltype(--std::declval<year&>() ));
+
+ static_assert(testConstexpr<year>(), "");
+
+ for (int i = 11000; i <= 11020; ++i)
+ {
+ year year(i);
+ assert(static_cast<int>(--year) == i - 1);
+ assert(static_cast<int>(year--) == i - 1);
+ assert(static_cast<int>(year) == i - 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/increment.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/increment.pass.cpp
new file mode 100644
index 000000000000..a6b60d6a07d8
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/increment.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year& operator++() noexcept;
+// constexpr year operator++(int) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y>
+constexpr bool testConstexpr()
+{
+ Y y1{10};
+ if (static_cast<int>(++y1) != 11) return false;
+ if (static_cast<int>(y1++) != 11) return false;
+ if (static_cast<int>(y1) != 12) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ ASSERT_NOEXCEPT(++(std::declval<year&>()) );
+ ASSERT_NOEXCEPT( (std::declval<year&>())++);
+
+ ASSERT_SAME_TYPE(year , decltype( std::declval<year&>()++));
+ ASSERT_SAME_TYPE(year&, decltype(++std::declval<year&>() ));
+
+ static_assert(testConstexpr<year>(), "");
+
+ for (int i = 11000; i <= 11020; ++i)
+ {
+ year year(i);
+ assert(static_cast<int>(++year) == i + 1);
+ assert(static_cast<int>(year++) == i + 1);
+ assert(static_cast<int>(year) == i + 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/is_leap.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/is_leap.pass.cpp
new file mode 100644
index 000000000000..73c0adb9837a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/is_leap.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr bool is_is_leap() const noexcept;
+// y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0)
+//
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+
+ ASSERT_NOEXCEPT( year(1).is_leap());
+ ASSERT_SAME_TYPE(bool, decltype(year(1).is_leap()));
+
+ static_assert(!year{1}.is_leap(), "");
+ static_assert(!year{2}.is_leap(), "");
+ static_assert(!year{3}.is_leap(), "");
+ static_assert( year{4}.is_leap(), "");
+
+ assert( year{-2000}.is_leap());
+ assert( year{ -400}.is_leap());
+ assert(!year{ -300}.is_leap());
+ assert(!year{ -200}.is_leap());
+
+ assert(!year{ 200}.is_leap());
+ assert(!year{ 300}.is_leap());
+ assert( year{ 400}.is_leap());
+ assert(!year{ 1997}.is_leap());
+ assert(!year{ 1998}.is_leap());
+ assert(!year{ 1999}.is_leap());
+ assert( year{ 2000}.is_leap());
+ assert(!year{ 2001}.is_leap());
+ assert(!year{ 2002}.is_leap());
+ assert(!year{ 2003}.is_leap());
+ assert( year{ 2004}.is_leap());
+ assert(!year{ 2100}.is_leap());
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ok.pass.cpp
new file mode 100644
index 000000000000..5f38b4c8c65c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ok.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr bool ok() const noexcept;
+// Returns: min() <= y_ && y_ <= max().
+//
+// static constexpr year min() noexcept;
+// Returns year{ 32767};
+// static constexpr year max() noexcept;
+// Returns year{-32767};
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+
+ ASSERT_NOEXCEPT( std::declval<const year>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year>().ok()));
+
+ ASSERT_NOEXCEPT( year::max());
+ ASSERT_SAME_TYPE(year, decltype(year::max()));
+
+ ASSERT_NOEXCEPT( year::min());
+ ASSERT_SAME_TYPE(year, decltype(year::min()));
+
+ static_assert(static_cast<int>(year::min()) == -32767, "");
+ static_assert(static_cast<int>(year::max()) == 32767, "");
+
+ assert(year{-20001}.ok());
+ assert(year{ -2000}.ok());
+ assert(year{ -1}.ok());
+ assert(year{ 0}.ok());
+ assert(year{ 1}.ok());
+ assert(year{ 2000}.ok());
+ assert(year{ 20001}.ok());
+
+ static_assert(!year{-32768}.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus.pass.cpp
new file mode 100644
index 000000000000..c74b5f8019d6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year operator+() const noexcept;
+// constexpr year operator-() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y>
+constexpr bool testConstexpr()
+{
+ Y y1{1};
+ if (static_cast<int>(+y1) != 1) return false;
+ if (static_cast<int>(-y1) != -1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+
+ ASSERT_NOEXCEPT(+std::declval<year>());
+ ASSERT_NOEXCEPT(-std::declval<year>());
+
+ ASSERT_SAME_TYPE(year, decltype(+std::declval<year>()));
+ ASSERT_SAME_TYPE(year, decltype(-std::declval<year>()));
+
+ static_assert(testConstexpr<year>(), "");
+
+ for (int i = 10000; i <= 10020; ++i)
+ {
+ year year(i);
+ assert(static_cast<int>(+year) == i);
+ assert(static_cast<int>(-year) == -i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus_equal.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus_equal.pass.cpp
new file mode 100644
index 000000000000..b457b7e91da5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus_equal.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year& operator+=(const years& d) noexcept;
+// constexpr year& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y, typename Ys>
+constexpr bool testConstexpr()
+{
+ Y y1{1};
+ if (static_cast<int>(y1 += Ys{ 1}) != 2) return false;
+ if (static_cast<int>(y1 += Ys{ 2}) != 4) return false;
+ if (static_cast<int>(y1 += Ys{ 8}) != 12) return false;
+ if (static_cast<int>(y1 -= Ys{ 1}) != 11) return false;
+ if (static_cast<int>(y1 -= Ys{ 2}) != 9) return false;
+ if (static_cast<int>(y1 -= Ys{ 8}) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT(std::declval<year&>() += std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<year&>() -= std::declval<years>());
+
+ ASSERT_SAME_TYPE(year&, decltype(std::declval<year&>() += std::declval<years>()));
+ ASSERT_SAME_TYPE(year&, decltype(std::declval<year&>() -= std::declval<years>()));
+
+ static_assert(testConstexpr<year, years>(), "");
+
+ for (int i = 10000; i <= 10020; ++i)
+ {
+ year year(i);
+ assert(static_cast<int>(year += years{10}) == i + 10);
+ assert(static_cast<int>(year) == i + 10);
+ assert(static_cast<int>(year -= years{ 9}) == i + 1);
+ assert(static_cast<int>(year) == i + 1);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..70bf9e11a613
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr bool operator==(const year& x, const year& y) noexcept;
+// constexpr bool operator!=(const year& x, const year& y) noexcept;
+// constexpr bool operator< (const year& x, const year& y) noexcept;
+// constexpr bool operator> (const year& x, const year& y) noexcept;
+// constexpr bool operator<=(const year& x, const year& y) noexcept;
+// constexpr bool operator>=(const year& x, const year& y) noexcept;
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+
+int main()
+{
+ using year = std::chrono::year;
+
+ AssertComparisons6AreNoexcept<year>();
+ AssertComparisons6ReturnBool<year>();
+
+ static_assert(testComparisons6Values<year>(0,0), "");
+ static_assert(testComparisons6Values<year>(0,1), "");
+
+// Some 'ok' values as well
+ static_assert(testComparisons6Values<year>( 5, 5), "");
+ static_assert(testComparisons6Values<year>( 5,10), "");
+
+ for (int i = 1; i < 10; ++i)
+ for (int j = 1; j < 10; ++j)
+ assert(testComparisons6Values<year>(i, j));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.fail.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.fail.cpp
new file mode 100644
index 000000000000..1d757ec08f82
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.fail.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-5, clang-6
+// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
+
+// <chrono>
+// class year;
+
+// constexpr year operator""y(unsigned long long y) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using std::chrono::year;
+ year d1 = 1234y; // expected-error-re {{no matching literal operator for call to 'operator""y' {{.*}}}}
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp
new file mode 100644
index 000000000000..0661567d8b7f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// UNSUPPORTED: clang-5, clang-6, clang-7
+// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
+
+// <chrono>
+// class year;
+
+// constexpr year operator""y(unsigned long long y) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ {
+ using namespace std::chrono;
+ ASSERT_NOEXCEPT(4y);
+
+ static_assert( 2017y == year(2017), "");
+ year y1 = 2018y;
+ assert (y1 == year(2018));
+ }
+
+ {
+ using namespace std::literals;
+ ASSERT_NOEXCEPT(4d);
+
+ static_assert( 2017y == std::chrono::year(2017), "");
+
+ std::chrono::year y1 = 2020y;
+ assert (y1 == std::chrono::year(2020));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..04cf9f617b3b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/minus.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year operator-(const year& x, const years& y) noexcept;
+// Returns: x + -y.
+//
+// constexpr years operator-(const year& x, const year& y) noexcept;
+// Returns: If x.ok() == true and y.ok() == true, returns a value m in the range
+// [years{0}, years{11}] satisfying y + m == x.
+// Otherwise the value returned is unspecified.
+// [Example: January - February == years{11}. —end example]
+
+extern "C" int printf(const char *, ...);
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y, typename Ys>
+constexpr bool testConstexpr()
+{
+ Y y{2313};
+ Ys offset{1006};
+ if (y - offset != Y{1307}) return false;
+ if (y - Y{1307} != offset) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT( std::declval<year>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year , decltype(std::declval<year>() - std::declval<years>()));
+
+ ASSERT_NOEXCEPT( std::declval<year>() - std::declval<year>());
+ ASSERT_SAME_TYPE(years, decltype(std::declval<year>() - std::declval<year>()));
+
+ static_assert(testConstexpr<year, years>(), "");
+
+ year y{1223};
+ for (int i = 1100; i <= 1110; ++i)
+ {
+ year y1 = y - years{i};
+ years ys1 = y - year{i};
+ assert(static_cast<int>(y1) == 1223 - i);
+ assert(ys1.count() == 1223 - i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..dfb3c5f982f2
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/plus.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+// constexpr year operator+(const year& x, const years& y) noexcept;
+// Returns: year(int{x} + y.count()).
+//
+// constexpr year operator+(const years& x, const year& y) noexcept;
+// Returns: y + x
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename Y, typename Ys>
+constexpr bool testConstexpr()
+{
+ Y y{1001};
+ Ys offset{23};
+ if (y + offset != Y{1024}) return false;
+ if (offset + y != Y{1024}) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT( std::declval<year>() + std::declval<years>());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<year>() + std::declval<years>()));
+
+ ASSERT_NOEXCEPT( std::declval<years>() + std::declval<year>());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<years>() + std::declval<year>()));
+
+ static_assert(testConstexpr<year, years>(), "");
+
+ year y{1223};
+ for (int i = 1100; i <= 1110; ++i)
+ {
+ year y1 = y + years{i};
+ year y2 = years{i} + y;
+ assert(y1 == y2);
+ assert(static_cast<int>(y1) == i + 1223);
+ assert(static_cast<int>(y2) == i + 1223);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..4bc92df215c5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year& y);
+//
+// Effects: Inserts format(fmt, y) where fmt is "%Y" widened to charT.
+// If !y.ok(), appends with " is not a valid year".
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const year& y);
+//
+// Effects: Streams y into os using the format specified by the NTCTS fmt.
+// fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// year& y, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the year y using the format flags
+// given in the NTCTS fmt as specified in 25.12. If the parse fails to decode a valid year,
+// is.setstate(ios_base::failbit) shall be called and y shall not be modified. If %Z is used
+// and successfully parsed, that value will be assigned to *abbrev if abbrev is non-null.
+// If %z (or a modified variant) is used and successfully parsed, that value will be
+// assigned to *offset if offset is non-null.
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+
+ std::cout << year{2018};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.year/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/types.pass.cpp
new file mode 100644
index 000000000000..92094b0c2185
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.year/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+
+ static_assert(std::is_trivially_copyable_v<year>, "");
+ static_assert(std::is_standard_layout_v<year>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ctor.pass.cpp
new file mode 100644
index 000000000000..4a1cc9087ff3
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ctor.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// year_month() = default;
+// constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept;
+//
+// Effects: Constructs an object of type year_month by initializing y_ with y, and m_ with m.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month = std::chrono::year_month;
+
+ ASSERT_NOEXCEPT(year_month{});
+ ASSERT_NOEXCEPT(year_month{year{1}, month{1}});
+
+ constexpr year_month ym0{};
+ static_assert( ym0.year() == year{}, "");
+ static_assert( ym0.month() == month{}, "");
+ static_assert(!ym0.ok(), "");
+
+ constexpr year_month ym1{year{2018}, std::chrono::January};
+ static_assert( ym1.year() == year{2018}, "");
+ static_assert( ym1.month() == std::chrono::January, "");
+ static_assert( ym1.ok(), "");
+
+ constexpr year_month ym2{year{2018}, month{}};
+ static_assert( ym2.year() == year{2018}, "");
+ static_assert( ym2.month() == month{}, "");
+ static_assert(!ym2.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/month.pass.cpp
new file mode 100644
index 000000000000..7a6dba18b814
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/month.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month = std::chrono::year_month;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const year_month>().month()));
+
+ static_assert( year_month{}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month ym(year{1234}, month{i});
+ assert( static_cast<unsigned>(ym.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ok.pass.cpp
new file mode 100644
index 000000000000..7e84b37ab3bf
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ok.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && y_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using month = std::chrono::month;
+ using year = std::chrono::year;
+ using year_month = std::chrono::year_month;
+
+ constexpr month January = std::chrono::January;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year_month>().ok()));
+
+ static_assert(!year_month{year{-32768}, January}.ok(), ""); // Bad year
+ static_assert(!year_month{year{2019}, month{}}.ok(), ""); // Bad month
+ static_assert( year_month{year{2019}, January}.ok(), ""); // Both OK
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month ym{year{2019}, month{i}};
+ assert( ym.ok() == month{i}.ok());
+ }
+
+ const int ymax = static_cast<int>(year::max());
+ for (int i = ymax - 100; i <= ymax + 100; ++i)
+ {
+ year_month ym{year{i}, January};
+ assert( ym.ok() == year{i}.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp
new file mode 100644
index 000000000000..44648c4a0241
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr year_month& operator+=(const months& d) noexcept;
+// constexpr year_month& operator-=(const months& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<unsigned>((d1 ).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 1}).month()) != 2) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 2}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 += Ds{12}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 1}).month()) != 3) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 2}).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 -= Ds{12}).month()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+ using year = std::chrono::year;
+ using year_month = std::chrono::year_month;
+
+ ASSERT_NOEXCEPT( std::declval<year_month&>() += std::declval<months>());
+ ASSERT_SAME_TYPE(year_month&, decltype(std::declval<year_month&>() += std::declval<months>()));
+
+ ASSERT_NOEXCEPT( std::declval<year_month&>() -= std::declval<months>());
+ ASSERT_SAME_TYPE(year_month&, decltype(std::declval<year_month&>() -= std::declval<months>()));
+
+ static_assert(testConstexpr<year_month, months>(year_month{year{1234}, month{1}}), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year y{1234};
+ year_month ym(y, month{i});
+ assert(static_cast<unsigned>((ym += months{2}).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym ).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym -= months{1}).month()) == i + 1);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym ).month()) == i + 1);
+ assert(ym.year() == y);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_year.pass.cpp
new file mode 100644
index 000000000000..073a2865614e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_year.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr year_month& operator+=(const years& d) noexcept;
+// constexpr year_month& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<int>((d1 ).year()) != 1) return false;
+ if (static_cast<int>((d1 += Ds{ 1}).year()) != 2) return false;
+ if (static_cast<int>((d1 += Ds{ 2}).year()) != 4) return false;
+ if (static_cast<int>((d1 += Ds{12}).year()) != 16) return false;
+ if (static_cast<int>((d1 -= Ds{ 1}).year()) != 15) return false;
+ if (static_cast<int>((d1 -= Ds{ 2}).year()) != 13) return false;
+ if (static_cast<int>((d1 -= Ds{12}).year()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using month = std::chrono::month;
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+ using year_month = std::chrono::year_month;
+
+
+ ASSERT_NOEXCEPT( std::declval<year_month&>() += std::declval<years>());
+ ASSERT_SAME_TYPE(year_month&, decltype(std::declval<year_month&>() += std::declval<years>()));
+
+ ASSERT_NOEXCEPT( std::declval<year_month&>() -= std::declval<years>());
+ ASSERT_SAME_TYPE(year_month&, decltype(std::declval<year_month&>() -= std::declval<years>()));
+
+ static_assert(testConstexpr<year_month, years>(year_month{year{1}, month{1}}), "");
+
+ for (int i = 1000; i <= 1010; ++i)
+ {
+ month m{2};
+ year_month ym(year{i}, m);
+ assert(static_cast<int>((ym += years{2}).year()) == i + 2);
+ assert(ym.month() == m);
+ assert(static_cast<int>((ym ).year()) == i + 2);
+ assert(ym.month() == m);
+ assert(static_cast<int>((ym -= years{1}).year()) == i + 1);
+ assert(ym.month() == m);
+ assert(static_cast<int>((ym ).year()) == i + 1);
+ assert(ym.month() == m);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/year.pass.cpp
new file mode 100644
index 000000000000..88e28026a9d2
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/year.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month = std::chrono::year_month;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month>().year());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<const year_month>().year()));
+
+ static_assert( year_month{}.year() == year{}, "");
+
+ for (int i = 1; i <= 50; ++i)
+ {
+ year_month ym(year{i}, month{});
+ assert( static_cast<int>(ym.year()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..d0c8d1e8cc1f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
+// Returns: x.year() == y.year() && x.month() == y.month().
+//
+// constexpr bool operator< (const year_month& x, const year_month& y) noexcept;
+// Returns:
+// If x.year() < y.year() returns true.
+// Otherwise, if x.year() > y.year() returns false.
+// Otherwise, returns x.month() < y.month().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month = std::chrono::year_month;
+
+ AssertComparisons6AreNoexcept<year_month>();
+ AssertComparisons6ReturnBool<year_month>();
+
+ static_assert( testComparisons6(
+ year_month{year{1234}, std::chrono::January},
+ year_month{year{1234}, std::chrono::January},
+ true, false), "");
+
+ static_assert( testComparisons6(
+ year_month{year{1234}, std::chrono::January},
+ year_month{year{1234}, std::chrono::February},
+ false, true), "");
+
+ static_assert( testComparisons6(
+ year_month{year{1234}, std::chrono::January},
+ year_month{year{1235}, std::chrono::January},
+ false, true), "");
+
+// same year, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons6(
+ year_month{year{1234}, month{i}},
+ year_month{year{1234}, month{j}},
+ i == j, i < j )));
+
+// same month, different years
+ for (int i = 1000; i < 20; ++i)
+ for (int j = 1000; j < 20; ++j)
+ assert((testComparisons6(
+ year_month{year{i}, std::chrono::January},
+ year_month{year{j}, std::chrono::January},
+ i == j, i < j )));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..1f77811accc0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
+// Returns: ym + -dy.
+//
+// constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
+// Returns: ym + -dm.
+//
+// constexpr months operator-(const year_month& x, const year_month& y) noexcept;
+// Returns: x.year() - y.year() + months{static_cast<int>(unsigned{x.month()}) -
+// static_cast<int>(unsigned{y.month()})}
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+int main()
+{
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+ using year_month = std::chrono::year_month;
+
+ { // year_month - years
+ ASSERT_NOEXCEPT( std::declval<year_month>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() - std::declval<years>()));
+
+// static_assert(testConstexprYears (year_month{year{1}, month{1}}), "");
+
+ year_month ym{year{1234}, std::chrono::January};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month ym1 = ym - years{i};
+ assert(static_cast<int>(ym1.year()) == 1234 - i);
+ assert(ym1.month() == std::chrono::January);
+ }
+ }
+
+ { // year_month - months
+ ASSERT_NOEXCEPT( std::declval<year_month>() - std::declval<months>());
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() - std::declval<months>()));
+
+// static_assert(testConstexprMonths(year_month{year{1}, month{1}}), "");
+
+ year_month ym{year{1234}, std::chrono::November};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month ym1 = ym - months{i};
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(ym1.month() == month(11 - i));
+ }
+ }
+
+ { // year_month - year_month
+ ASSERT_NOEXCEPT( std::declval<year_month>() - std::declval<year_month>());
+ ASSERT_SAME_TYPE(months, decltype(std::declval<year_month>() - std::declval<year_month>()));
+
+// static_assert(testConstexprMonths(year_month{year{1}, month{1}}), "");
+
+// Same year
+ year y{2345};
+ for (int i = 1; i <= 12; ++i)
+ for (int j = 1; j <= 12; ++j)
+ {
+ months diff = year_month{y, month(i)} - year_month{y, month(j)};
+ std::cout << "i: " << i << " j: " << j << " -> " << diff.count() << std::endl;
+ assert(diff.count() == i - j);
+ }
+
+// TODO: different year
+
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..67616764d3c5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+// constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
+// Returns: (ym.year() + dy) / ym.month().
+//
+// constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
+// Returns: ym + dy.
+//
+// constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
+// Returns: A year_month value z such that z - ym == dm.
+// Complexity: O(1) with respect to the value of dm.
+//
+// constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
+// Returns: ym + dm.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool testConstexprYears(std::chrono::year_month ym)
+{
+ std::chrono::years offset{23};
+ if (static_cast<int>((ym ).year()) != 1) return false;
+ if (static_cast<int>((ym + offset).year()) != 24) return false;
+ if (static_cast<int>((offset + ym).year()) != 24) return false;
+ return true;
+}
+
+
+constexpr bool testConstexprMonths(std::chrono::year_month ym)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ym ).month()) != 1) return false;
+ if (static_cast<unsigned>((ym + offset).month()) != 7) return false;
+ if (static_cast<unsigned>((offset + ym).month()) != 7) return false;
+ return true;
+}
+
+
+int main()
+{
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+ using year_month = std::chrono::year_month;
+
+ { // year_month + years
+ ASSERT_NOEXCEPT(std::declval<year_month>() + std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month>());
+
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<years>() + std::declval<year_month>()));
+
+ static_assert(testConstexprYears (year_month{year{1}, month{1}}), "");
+
+ year_month ym{year{1234}, std::chrono::January};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month ym1 = ym + years{i};
+ year_month ym2 = years{i} + ym;
+ assert(static_cast<int>(ym1.year()) == i + 1234);
+ assert(static_cast<int>(ym2.year()) == i + 1234);
+ assert(ym1.month() == std::chrono::January);
+ assert(ym2.month() == std::chrono::January);
+ assert(ym1 == ym2);
+ }
+ }
+
+ { // year_month + months
+ ASSERT_NOEXCEPT(std::declval<year_month>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month>());
+
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<months>() + std::declval<year_month>()));
+
+ static_assert(testConstexprMonths(year_month{year{1}, month{1}}), "");
+
+ year_month ym{year{1234}, std::chrono::January};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month ym1 = ym + months{i};
+ year_month ym2 = months{i} + ym;
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(static_cast<int>(ym2.year()) == 1234);
+ assert(ym1.month() == month(1 + i));
+ assert(ym2.month() == month(1 + i));
+ assert(ym1 == ym2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..8679c9612118
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year_month;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year_month& ym);
+//
+// Returns: os << ym.year() << '/' << ym.month().
+//
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const year_month& ym);
+//
+// Effects: Streams ym into os using the format specified by the NTCTS fmt. fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// year_month& ym, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the year_month ym using the format
+// flags given in the NTCTS fmt as specified in 25.12. If the parse fails to decode
+// a valid year_month, is.setstate(ios_- base::failbit) shall be called and ym shall
+// not be modified. If %Z is used and successfully parsed, that value will be assigned
+// to *abbrev if abbrev is non-null. If %z (or a modified variant) is used and
+// successfully parsed, that value will be assigned to *offset if offset is non-null.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month = std::chrono::year_month;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+
+ std::cout << year_month{year{2018}, month{3}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ym/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ym/types.pass.cpp
new file mode 100644
index 000000000000..200e2874d224
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ym/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month = std::chrono::year_month;
+
+ static_assert(std::is_trivially_copyable_v<year_month>, "");
+ static_assert(std::is_standard_layout_v<year_month>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp
new file mode 100644
index 000000000000..5c7de1418fbd
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// explicit constexpr year_month_day(const local_days& dp) noexcept;
+//
+//
+// Effects: Constructs an object of type year_month_day that corresponds
+// to the date represented by dp
+//
+// Remarks: Equivalent to constructing with sys_days{dp.time_since_epoch()}.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::day day() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using day = std::chrono::day;
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(year_month_day{std::declval<local_days>()});
+
+ {
+ constexpr local_days sd{};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{1970}, "");
+ static_assert( ymd.month() == std::chrono::January, "");
+ static_assert( ymd.day() == day{1}, "");
+ }
+
+ {
+ constexpr local_days sd{days{10957+32}};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{2000}, "");
+ static_assert( ymd.month() == std::chrono::February, "");
+ static_assert( ymd.day() == day{2}, "");
+ }
+
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr local_days sd{days{-10957}};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{1940}, "");
+ static_assert( ymd.month() == std::chrono::January, "");
+ static_assert( ymd.day() == day{2}, "");
+ }
+
+ {
+ local_days sd{days{-(10957+34)}};
+ year_month_day ymd{sd};
+
+ assert( ymd.ok());
+ assert( ymd.year() == year{1939});
+ assert( ymd.month() == std::chrono::November);
+ assert( ymd.day() == day{29});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.pass.cpp
new file mode 100644
index 000000000000..e2e0ac38ca93
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// year_month_day() = default;
+// constexpr year_month_day(const chrono::year& y, const chrono::month& m,
+// const chrono::day& d) noexcept;
+//
+// Effects: Constructs an object of type year_month_day by initializing
+// y_ with y, m_ with m, and d_ with d.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::day day() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(year_month_day{});
+ ASSERT_NOEXCEPT(year_month_day{year{1}, month{1}, day{1}});
+
+ constexpr month January = std::chrono::January;
+
+ constexpr year_month_day ym0{};
+ static_assert( ym0.year() == year{}, "");
+ static_assert( ym0.month() == month{}, "");
+ static_assert( ym0.day() == day{}, "");
+ static_assert(!ym0.ok(), "");
+
+ constexpr year_month_day ym1{year{2019}, January, day{12}};
+ static_assert( ym1.year() == year{2019}, "");
+ static_assert( ym1.month() == January, "");
+ static_assert( ym1.day() == day{12}, "");
+ static_assert( ym1.ok(), "");
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp
new file mode 100644
index 000000000000..36a6c7d180c1
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day(const sys_days& dp) noexcept;
+//
+// Effects: Constructs an object of type year_month_day that corresponds
+// to the date represented by dp.
+//
+// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true,
+// ymd == year_month_day{sys_days{ymd}} is true.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using day = std::chrono::day;
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(year_month_day{std::declval<sys_days>()});
+
+ {
+ constexpr sys_days sd{};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{1970}, "");
+ static_assert( ymd.month() == std::chrono::January, "");
+ static_assert( ymd.day() == day{1}, "");
+ }
+
+ {
+ constexpr sys_days sd{days{10957+32}};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{2000}, "");
+ static_assert( ymd.month() == std::chrono::February, "");
+ static_assert( ymd.day() == day{2}, "");
+ }
+
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr sys_days sd{days{-10957}};
+ constexpr year_month_day ymd{sd};
+
+ static_assert( ymd.ok(), "");
+ static_assert( ymd.year() == year{1940}, "");
+ static_assert( ymd.month() == std::chrono::January, "");
+ static_assert( ymd.day() == day{2}, "");
+ }
+
+ {
+ sys_days sd{days{-(10957+34)}};
+ year_month_day ymd{sd};
+
+ assert( ymd.ok());
+ assert( ymd.year() == year{1939});
+ assert( ymd.month() == std::chrono::November);
+ assert( ymd.day() == day{29});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp
new file mode 100644
index 000000000000..a8d6526b328a
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day(const year_month_day_last& ymdl) noexcept;
+//
+// Effects: Constructs an object of type year_month_day by initializing
+// y_ with ymdl.year(), m_ with ymdl.month(), and d_ with ymdl.day().
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::day day() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(year_month_day{std::declval<const year_month_day_last>()});
+
+ {
+ constexpr year_month_day_last ymdl{year{2019}, month_day_last{month{1}}};
+ constexpr year_month_day ymd{ymdl};
+
+ static_assert( ymd.year() == year{2019}, "");
+ static_assert( ymd.month() == month{1}, "");
+ static_assert( ymd.day() == day{31}, "");
+ static_assert( ymd.ok(), "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{1970}, month_day_last{month{4}}};
+ constexpr year_month_day ymd{ymdl};
+
+ static_assert( ymd.year() == year{1970}, "");
+ static_assert( ymd.month() == month{4}, "");
+ static_assert( ymd.day() == day{30}, "");
+ static_assert( ymd.ok(), "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{2000}, month_day_last{month{2}}};
+ constexpr year_month_day ymd{ymdl};
+
+ static_assert( ymd.year() == year{2000}, "");
+ static_assert( ymd.month() == month{2}, "");
+ static_assert( ymd.day() == day{29}, "");
+ static_assert( ymd.ok(), "");
+ }
+
+ { // Feb 1900 was NOT a leap year.
+ year_month_day_last ymdl{year{1900}, month_day_last{month{2}}};
+ year_month_day ymd{ymdl};
+
+ assert( ymd.year() == year{1900});
+ assert( ymd.month() == month{2});
+ assert( ymd.day() == day{28});
+ assert( ymd.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/day.pass.cpp
new file mode 100644
index 000000000000..c46b9ce85129
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/day.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day>().day());
+ ASSERT_SAME_TYPE(day, decltype(std::declval<const year_month_day>().day()));
+
+ static_assert( year_month_day{}.day() == day{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_day ymd(year{1234}, month{2}, day{i});
+ assert( static_cast<unsigned>(ymd.day()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/month.pass.cpp
new file mode 100644
index 000000000000..b3c03041e892
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/month.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const year_month_day>().month()));
+
+ static_assert( year_month_day{}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_day ymd(year{1234}, month{i}, day{12});
+ assert( static_cast<unsigned>(ymd.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp
new file mode 100644
index 000000000000..cab0599b9ed3
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && y_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+
+ constexpr month January = std::chrono::January;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year_month_day>().ok()));
+
+ static_assert(!year_month_day{year{-32768}, month{}, day{}}.ok(), ""); // All three bad
+
+ static_assert(!year_month_day{year{-32768}, January, day{1}}.ok(), ""); // Bad year
+ static_assert(!year_month_day{year{2019}, month{}, day{1}}.ok(), ""); // Bad month
+ static_assert(!year_month_day{year{2019}, January, day{} }.ok(), ""); // Bad day
+
+ static_assert(!year_month_day{year{-32768}, month{}, day{1}}.ok(), ""); // Bad year & month
+ static_assert(!year_month_day{year{2019}, month{}, day{} }.ok(), ""); // Bad month & day
+ static_assert(!year_month_day{year{-32768}, January, day{} }.ok(), ""); // Bad year & day
+
+ static_assert( year_month_day{year{2019}, January, day{1}}.ok(), ""); // All OK
+
+// Some months have a 31st
+ static_assert( year_month_day{year{2020}, month{ 1}, day{31}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{ 2}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 3}, day{31}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{ 4}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 5}, day{31}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{ 6}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 7}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 8}, day{31}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{ 9}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{10}, day{31}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{11}, day{31}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{12}, day{31}}.ok(), "");
+
+// Everyone except FEB has a 30th
+ static_assert( year_month_day{year{2020}, month{ 1}, day{30}}.ok(), "");
+ static_assert(!year_month_day{year{2020}, month{ 2}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 3}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 4}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 5}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 6}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 7}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 8}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{ 9}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{10}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{11}, day{30}}.ok(), "");
+ static_assert( year_month_day{year{2020}, month{12}, day{30}}.ok(), "");
+
+ static_assert(!year_month_day{year{2019}, std::chrono::February, day{29}}.ok(), ""); // Not a leap year
+ static_assert( year_month_day{year{2020}, std::chrono::February, day{29}}.ok(), ""); // Ok; 2020 is a leap year
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_day ym{year{2019}, January, day{i}};
+ assert( ym.ok() == day{i}.ok());
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_day ym{year{2019}, month{i}, day{12}};
+ assert( ym.ok() == month{i}.ok());
+ }
+
+ const int ymax = static_cast<int>(year::max());
+ for (int i = ymax - 100; i <= ymax + 100; ++i)
+ {
+ year_month_day ym{year{i}, January, day{12}};
+ assert( ym.ok() == year{i}.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp
new file mode 100644
index 000000000000..a70fe30fc5db
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.local_days.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr operator local_days() const noexcept;
+//
+// Returns: If ok(), returns a local_days holding a count of days from the
+// local_days epoch to *this (a negative value if *this represents a date
+// prior to the sys_days epoch). Otherwise, if y_.ok() && m_.ok() is true,
+// returns a sys_days which is offset from sys_days{y_/m_/last} by the
+// number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise
+// the value returned is unspecified.
+//
+// Remarks: A local_days in the range [days{-12687428}, days{11248737}] which
+// is converted to a year_month_day shall have the same value when
+// converted back to a sys_days.
+//
+// [Example:
+// static_assert(year_month_day{local_days{2017y/January/0}} == 2016y/December/31);
+// static_assert(year_month_day{local_days{2017y/January/31}} == 2017y/January/31);
+// static_assert(year_month_day{local_days{2017y/January/32}} == 2017y/February/1);
+// —end example]
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+void RunTheExample()
+{
+ using namespace std::chrono;
+
+ static_assert(year_month_day{local_days{year{2017}/January/0}} == year{2016}/December/31);
+ static_assert(year_month_day{local_days{year{2017}/January/31}} == year{2017}/January/31);
+ static_assert(year_month_day{local_days{year{2017}/January/32}} == year{2017}/February/1);
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(local_days(std::declval<year_month_day>()));
+ RunTheExample();
+
+ {
+ constexpr year_month_day ymd{year{1970}, month{1}, day{1}};
+ constexpr local_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{0}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+ {
+ constexpr year_month_day ymd{year{2000}, month{2}, day{2}};
+ constexpr local_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{10957+32}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr year_month_day ymd{year{1940}, month{1}, day{2}};
+ constexpr local_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{-10957}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+ {
+ year_month_day ymd{year{1939}, month{11}, day{29}};
+ local_days sd{ymd};
+
+ assert( sd.time_since_epoch() == days{-(10957+34)});
+ assert( year_month_day{sd} == ymd); // and back
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp
new file mode 100644
index 000000000000..4e263bcccb6b
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/op.sys_days.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr operator sys_days() const noexcept;
+//
+// Returns: If ok(), returns a sys_days holding a count of days from the
+// sys_days epoch to *this (a negative value if *this represents a date
+// prior to the sys_days epoch). Otherwise, if y_.ok() && m_.ok() is true,
+// returns a sys_days which is offset from sys_days{y_/m_/last} by the
+// number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise
+// the value returned is unspecified.
+//
+// Remarks: A sys_days in the range [days{-12687428}, days{11248737}] which
+// is converted to a year_month_day shall have the same value when
+// converted back to a sys_days.
+//
+// [Example:
+// static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31);
+// static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31);
+// static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1);
+// —end example]
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+void RunTheExample()
+{
+ using namespace std::chrono;
+
+ static_assert(year_month_day{sys_days{year{2017}/January/0}} == year{2016}/December/31);
+ static_assert(year_month_day{sys_days{year{2017}/January/31}} == year{2017}/January/31);
+ static_assert(year_month_day{sys_days{year{2017}/January/32}} == year{2017}/February/1);
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT(sys_days(std::declval<year_month_day>()));
+ RunTheExample();
+
+ {
+ constexpr year_month_day ymd{year{1970}, month{1}, day{1}};
+ constexpr sys_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{0}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+ {
+ constexpr year_month_day ymd{year{2000}, month{2}, day{2}};
+ constexpr sys_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{10957+32}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr year_month_day ymd{year{1940}, month{1}, day{2}};
+ constexpr sys_days sd{ymd};
+
+ static_assert( sd.time_since_epoch() == days{-10957}, "");
+ static_assert( year_month_day{sd} == ymd, ""); // and back
+ }
+
+ {
+ year_month_day ymd{year{1939}, month{11}, day{29}};
+ sys_days sd{ymd};
+
+ assert( sd.time_since_epoch() == days{-(10957+34)});
+ assert( year_month_day{sd} == ymd); // and back
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp
new file mode 100644
index 000000000000..7cd31222daa0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day& operator+=(const months& m) noexcept;
+// constexpr year_month_day& operator-=(const months& m) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<unsigned>((d1 ).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 1}).month()) != 2) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 2}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 += Ds{12}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 1}).month()) != 3) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 2}).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 -= Ds{12}).month()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_day&>() += std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<year_month_day&>() -= std::declval<months>());
+
+ ASSERT_SAME_TYPE(year_month_day&, decltype(std::declval<year_month_day&>() += std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_day&, decltype(std::declval<year_month_day&>() -= std::declval<months>()));
+
+ static_assert(testConstexpr<year_month_day, months>(year_month_day{year{1234}, month{1}, day{1}}), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year y{1234};
+ day d{23};
+ year_month_day ym(y, month{i}, d);
+ assert(static_cast<unsigned>((ym += months{2}).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(ym.day() == d);
+ assert(static_cast<unsigned>((ym ).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(ym.day() == d);
+ assert(static_cast<unsigned>((ym -= months{1}).month()) == i + 1);
+ assert(ym.year() == y);
+ assert(ym.day() == d);
+ assert(static_cast<unsigned>((ym ).month()) == i + 1);
+ assert(ym.year() == y);
+ assert(ym.day() == d);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_year.pass.cpp
new file mode 100644
index 000000000000..650941dc945e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_year.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day& operator+=(const years& d) noexcept;
+// constexpr year_month_day& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<int>((d1 ).year()) != 1) return false;
+ if (static_cast<int>((d1 += Ds{ 1}).year()) != 2) return false;
+ if (static_cast<int>((d1 += Ds{ 2}).year()) != 4) return false;
+ if (static_cast<int>((d1 += Ds{12}).year()) != 16) return false;
+ if (static_cast<int>((d1 -= Ds{ 1}).year()) != 15) return false;
+ if (static_cast<int>((d1 -= Ds{ 2}).year()) != 13) return false;
+ if (static_cast<int>((d1 -= Ds{12}).year()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_day&>() += std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<year_month_day&>() -= std::declval<years>());
+
+ ASSERT_SAME_TYPE(year_month_day&, decltype(std::declval<year_month_day&>() += std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_day&, decltype(std::declval<year_month_day&>() -= std::declval<years>()));
+
+ static_assert(testConstexpr<year_month_day, years>(year_month_day{year{1}, month{1}, day{1}}), "");
+
+ for (int i = 1000; i <= 1010; ++i)
+ {
+ month m{2};
+ day d{23};
+ year_month_day ym(year{i}, m, d);
+ assert(static_cast<int>((ym += years{2}).year()) == i + 2);
+ assert(ym.month() == m);
+ assert(ym.day() == d);
+ assert(static_cast<int>((ym ).year()) == i + 2);
+ assert(ym.month() == m);
+ assert(ym.day() == d);
+ assert(static_cast<int>((ym -= years{1}).year()) == i + 1);
+ assert(ym.month() == m);
+ assert(ym.day() == d);
+ assert(static_cast<int>((ym ).year()) == i + 1);
+ assert(ym.month() == m);
+ assert(ym.day() == d);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/year.pass.cpp
new file mode 100644
index 000000000000..be6aa5c575d9
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/year.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day>().year());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<const year_month_day>().year()));
+
+ static_assert( year_month_day{}.year() == year{}, "");
+
+ for (int i = 1; i <= 50; ++i)
+ {
+ year_month_day ym(year{i}, month{}, day{});
+ assert( static_cast<int>(ym.year()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..0df684395d45
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
+// Returns: x.year() == y.year() && x.month() == y.month().
+//
+// constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
+// Returns:
+// If x.year() < y.year() returns true.
+// Otherwise, if x.year() > y.year() returns false.
+// Otherwise, if x.month() < y.month() returns true.
+// Otherwise, if x.month() > y.month() returns false.
+// Otherwise, returns x.day() < y.day()
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using day = std::chrono::day;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month_day = std::chrono::year_month_day;
+
+ AssertComparisons6AreNoexcept<year_month_day>();
+ AssertComparisons6ReturnBool<year_month_day>();
+
+ constexpr month January = std::chrono::January;
+ constexpr month February = std::chrono::February;
+
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{1}},
+ year_month_day{year{1234}, January, day{1}},
+ true, false), "");
+
+// different day
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{1}},
+ year_month_day{year{1234}, January, day{2}},
+ false, true), "");
+
+// different month
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{1}},
+ year_month_day{year{1234}, February, day{1}},
+ false, true), "");
+
+// different year
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{1}},
+ year_month_day{year{1235}, January, day{1}},
+ false, true), "");
+
+
+// different month and day
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{2}},
+ year_month_day{year{1234}, February, day{1}},
+ false, true), "");
+
+// different year and month
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, February, day{1}},
+ year_month_day{year{1235}, January, day{1}},
+ false, true), "");
+
+// different year and day
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, January, day{2}},
+ year_month_day{year{1235}, January, day{1}},
+ false, true), "");
+
+// different year, month and day
+ static_assert( testComparisons6(
+ year_month_day{year{1234}, February, day{2}},
+ year_month_day{year{1235}, January, day{1}},
+ false, true), "");
+
+
+// same year, different days
+ for (unsigned i = 1; i < 28; ++i)
+ for (unsigned j = 1; j < 28; ++j)
+ assert((testComparisons6(
+ year_month_day{year{1234}, January, day{i}},
+ year_month_day{year{1234}, January, day{j}},
+ i == j, i < j )));
+
+// same year, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons6(
+ year_month_day{year{1234}, month{i}, day{12}},
+ year_month_day{year{1234}, month{j}, day{12}},
+ i == j, i < j )));
+
+// same month, different years
+ for (int i = 1000; i < 20; ++i)
+ for (int j = 1000; j < 20; ++j)
+ assert((testComparisons6(
+ year_month_day{year{i}, January, day{12}},
+ year_month_day{year{j}, January, day{12}},
+ i == j, i < j )));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..41b61f7b6854
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/minus.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
+// Returns: ymd + (-dy)
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+constexpr bool test_constexpr ()
+{
+ std::chrono::year_month_day ym0{std::chrono::year{1234}, std::chrono::January, std::chrono::day{12}};
+ std::chrono::year_month_day ym1 = ym0 - std::chrono::years{10};
+ return
+ ym1.year() == std::chrono::year{1234-10}
+ && ym1.month() == std::chrono::January
+ && ym1.day() == std::chrono::day{12}
+ ;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using year_month_day = std::chrono::year_month_day;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT( std::declval<year_month_day>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_day, decltype(std::declval<year_month_day>() - std::declval<years>()));
+
+ constexpr month January = std::chrono::January;
+
+ static_assert(test_constexpr(), "");
+
+ year_month_day ym{year{1234}, January, day{10}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_day ym1 = ym - years{i};
+ assert(static_cast<int>(ym1.year()) == 1234 - i);
+ assert(ym1.month() == January);
+ assert(ym1.day() == day{10});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..c325d1f89ac4
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+// constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
+// Returns: (ymd.year() / ymd.month() + dm) / ymd.day().
+//
+// constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
+// Returns: ymd + dm.
+//
+//
+// constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
+// Returns: (ymd.year() + dy) / ymd.month() / ymd.day().
+//
+// constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
+// Returns: ym + dm.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool testConstexprYears(std::chrono::year_month_day ym)
+{
+ std::chrono::years offset{23};
+ if (static_cast<int>((ym ).year()) != 1) return false;
+ if (static_cast<int>((ym + offset).year()) != 24) return false;
+ if (static_cast<int>((offset + ym).year()) != 24) return false;
+ return true;
+}
+
+
+constexpr bool testConstexprMonths(std::chrono::year_month_day ym)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ym ).month()) != 1) return false;
+ if (static_cast<unsigned>((ym + offset).month()) != 7) return false;
+ if (static_cast<unsigned>((offset + ym).month()) != 7) return false;
+ return true;
+}
+
+
+int main()
+{
+ using day = std::chrono::day;
+ using year = std::chrono::year;
+ using years = std::chrono::years;
+ using month = std::chrono::month;
+ using months = std::chrono::months;
+ using year_month_day = std::chrono::year_month_day;
+
+ { // year_month_day + months
+ ASSERT_NOEXCEPT(std::declval<year_month_day>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month_day>());
+
+ ASSERT_SAME_TYPE(year_month_day, decltype(std::declval<year_month_day>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_day, decltype(std::declval<months>() + std::declval<year_month_day>()));
+
+ static_assert(testConstexprMonths(year_month_day{year{1}, month{1}, day{1}}), "");
+
+ year_month_day ym{year{1234}, std::chrono::January, day{12}};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month_day ym1 = ym + months{i};
+ year_month_day ym2 = months{i} + ym;
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(static_cast<int>(ym2.year()) == 1234);
+ assert(ym1.month() == month(1 + i));
+ assert(ym2.month() == month(1 + i));
+ assert(ym1.day() == day{12});
+ assert(ym2.day() == day{12});
+ assert(ym1 == ym2);
+ }
+ }
+
+ { // year_month_day + years
+ ASSERT_NOEXCEPT(std::declval<year_month_day>() + std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month_day>());
+
+ ASSERT_SAME_TYPE(year_month_day, decltype(std::declval<year_month_day>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_day, decltype(std::declval<years>() + std::declval<year_month_day>()));
+
+ static_assert(testConstexprYears (year_month_day{year{1}, month{1}, day{1}}), "");
+
+ year_month_day ym{year{1234}, std::chrono::January, day{12}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_day ym1 = ym + years{i};
+ year_month_day ym2 = years{i} + ym;
+ assert(static_cast<int>(ym1.year()) == i + 1234);
+ assert(static_cast<int>(ym2.year()) == i + 1234);
+ assert(ym1.month() == std::chrono::January);
+ assert(ym2.month() == std::chrono::January);
+ assert(ym1.day() == day{12});
+ assert(ym2.day() == day{12});
+ assert(ym1 == ym2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..4bfca15494d9
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year_month_day;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year_month_day& ym);
+//
+// Returns: os << ym.year() << '/' << ym.month().
+//
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const year_month_day& ym);
+//
+// Effects: Streams ym into os using the format specified by the NTCTS fmt. fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// year_month_day& ym, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the year_month_day ym using the format
+// flags given in the NTCTS fmt as specified in 25.12. If the parse fails to decode
+// a valid year_month_day, is.setstate(ios_- base::failbit) shall be called and ym shall
+// not be modified. If %Z is used and successfully parsed, that value will be assigned
+// to *abbrev if abbrev is non-null. If %z (or a modified variant) is used and
+// successfully parsed, that value will be assigned to *offset if offset is non-null.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_day = std::chrono::year_month_day;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+
+ std::cout << year_month_day{year{2018}, month{3}, day{12}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymd/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/types.pass.cpp
new file mode 100644
index 000000000000..f13f4da1a5fd
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymd/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_day = std::chrono::year_month_day;
+
+ static_assert(std::is_trivially_copyable_v<year_month_day>, "");
+ static_assert(std::is_standard_layout_v<year_month_day>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ctor.pass.cpp
new file mode 100644
index 000000000000..e2a6a7acf280
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ctor.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last(const chrono::year& y,
+// const chrono::month_day_last& mdl) noexcept;
+//
+// Effects: Constructs an object of type year_month_day_last by initializing
+// initializing y_ with y and mdl_ with mdl.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::month_day_last month_day_last() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ ASSERT_NOEXCEPT(year_month_day_last{year{1}, month_day_last{month{1}}});
+
+ constexpr month January = std::chrono::January;
+
+ constexpr year_month_day_last ymdl0{year{}, month_day_last{month{}}};
+ static_assert( ymdl0.year() == year{}, "");
+ static_assert( ymdl0.month() == month{}, "");
+ static_assert( ymdl0.month_day_last() == month_day_last{month{}}, "");
+ static_assert(!ymdl0.ok(), "");
+
+ constexpr year_month_day_last ymdl1{year{2019}, month_day_last{January}};
+ static_assert( ymdl1.year() == year{2019}, "");
+ static_assert( ymdl1.month() == January, "");
+ static_assert( ymdl1.month_day_last() == month_day_last{January}, "");
+ static_assert( ymdl1.ok(), "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp
new file mode 100644
index 000000000000..db3369c6c8a4
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using day = std::chrono::day;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().day());
+ ASSERT_SAME_TYPE(day, decltype(std::declval<const year_month_day_last>().day()));
+
+// Some months have a 31st
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 1}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 2}}}.day() == day{29}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 3}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 4}}}.day() == day{30}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 5}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 6}}}.day() == day{30}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 7}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 8}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{ 9}}}.day() == day{30}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{10}}}.day() == day{31}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{11}}}.day() == day{30}, "");
+ static_assert( year_month_day_last{year{2020}, month_day_last{month{12}}}.day() == day{31}, "");
+
+ assert((year_month_day_last{year{2019}, month_day_last{month{ 2}}}.day() == day{28}));
+ assert((year_month_day_last{year{2020}, month_day_last{month{ 2}}}.day() == day{29}));
+ assert((year_month_day_last{year{2021}, month_day_last{month{ 2}}}.day() == day{28}));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month.pass.cpp
new file mode 100644
index 000000000000..43ec42d94e10
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const year_month_day_last>().month()));
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_day_last ymd(year{1234}, month_day_last{month{i}});
+ assert( static_cast<unsigned>(ymd.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month_day_last.pass.cpp
new file mode 100644
index 000000000000..613cc1c6b3e1
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month_day_last.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().month_day_last());
+ ASSERT_SAME_TYPE(month_day_last, decltype(std::declval<const year_month_day_last>().month_day_last()));
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_day_last ymdl(year{1234}, month_day_last{month{i}});
+ assert( static_cast<unsigned>(ymdl.month_day_last().month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ok.pass.cpp
new file mode 100644
index 000000000000..7b61214b7a23
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ok.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && y_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ constexpr month January = std::chrono::January;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year_month_day_last>().ok()));
+
+ static_assert(!year_month_day_last{year{-32768}, month_day_last{month{}}}.ok(), ""); // both bad
+ static_assert(!year_month_day_last{year{-32768}, month_day_last{January}}.ok(), ""); // Bad year
+ static_assert(!year_month_day_last{year{2019}, month_day_last{month{}}}.ok(), ""); // Bad month
+ static_assert( year_month_day_last{year{2019}, month_day_last{January}}.ok(), ""); // All OK
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_day_last ym{year{2019}, month_day_last{month{i}}};
+ assert( ym.ok() == month{i}.ok());
+ }
+
+ const int ymax = static_cast<int>(year::max());
+ for (int i = ymax - 100; i <= ymax + 100; ++i)
+ {
+ year_month_day_last ym{year{i}, month_day_last{January}};
+ assert( ym.ok() == year{i}.ok());
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp
new file mode 100644
index 000000000000..45f1ac4ae2d6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr operator local_days() const noexcept;
+// Returns: local_days{sys_days{*this}.time_since_epoch()}.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( static_cast<local_days>(std::declval<const year_month_day_last>()));
+ ASSERT_SAME_TYPE(local_days, decltype(static_cast<local_days>(std::declval<const year_month_day_last>())));
+
+ { // Last day in Jan 1970 was the 31st
+ constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{10957+30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{-10957+29}, "");
+ }
+
+ {
+ year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}};
+ local_days sd{ymdl};
+
+ assert(sd.time_since_epoch() == days{-(10957+33)});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp
new file mode 100644
index 000000000000..20aff6d1db8c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr operator sys_days() const noexcept;
+// Returns: sys_days{year()/month()/day()}.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( static_cast<sys_days>(std::declval<const year_month_day_last>()));
+ ASSERT_SAME_TYPE(sys_days, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>())));
+
+ { // Last day in Jan 1970 was the 31st
+ constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}};
+ constexpr sys_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}};
+ constexpr sys_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{10957+30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}};
+ constexpr sys_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{-10957+29}, "");
+ }
+
+ {
+ year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}};
+ sys_days sd{ymdl};
+
+ assert(sd.time_since_epoch() == days{-(10957+33)});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp
new file mode 100644
index 000000000000..bfa1d58d9082
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last& operator+=(const months& m) noexcept;
+// constexpr year_month_day_last& operator-=(const months& m) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<unsigned>((d1 ).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 1}).month()) != 2) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 2}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 += Ds{12}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 1}).month()) != 3) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 2}).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 -= Ds{12}).month()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last&>() += std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last&>() -= std::declval<months>());
+
+ ASSERT_SAME_TYPE(year_month_day_last&, decltype(std::declval<year_month_day_last&>() += std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_day_last&, decltype(std::declval<year_month_day_last&>() -= std::declval<months>()));
+
+ static_assert(testConstexpr<year_month_day_last, months>(year_month_day_last{year{1234}, month_day_last{month{1}}}), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year y{1234};
+ month_day_last mdl{month{i}};
+ year_month_day_last ym(y, mdl);
+ assert(static_cast<unsigned>((ym += months{2}).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym ).month()) == i + 2);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym -= months{1}).month()) == i + 1);
+ assert(ym.year() == y);
+ assert(static_cast<unsigned>((ym ).month()) == i + 1);
+ assert(ym.year() == y);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_year.pass.cpp
new file mode 100644
index 000000000000..ce364d2361ed
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_year.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last& operator+=(const years& d) noexcept;
+// constexpr year_month_day_last& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<int>((d1 ).year()) != 1) return false;
+ if (static_cast<int>((d1 += Ds{ 1}).year()) != 2) return false;
+ if (static_cast<int>((d1 += Ds{ 2}).year()) != 4) return false;
+ if (static_cast<int>((d1 += Ds{12}).year()) != 16) return false;
+ if (static_cast<int>((d1 -= Ds{ 1}).year()) != 15) return false;
+ if (static_cast<int>((d1 -= Ds{ 2}).year()) != 13) return false;
+ if (static_cast<int>((d1 -= Ds{12}).year()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last&>() += std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last&>() -= std::declval<years>());
+
+ ASSERT_SAME_TYPE(year_month_day_last&, decltype(std::declval<year_month_day_last&>() += std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_day_last&, decltype(std::declval<year_month_day_last&>() -= std::declval<years>()));
+
+ static_assert(testConstexpr<year_month_day_last, years>(year_month_day_last{year{1}, month_day_last{month{1}}}), "");
+
+ for (int i = 1000; i <= 1010; ++i)
+ {
+ month_day_last mdl{month{2}};
+ year_month_day_last ymdl(year{i}, mdl);
+ assert(static_cast<int>((ymdl += years{2}).year()) == i + 2);
+ assert(ymdl.month_day_last() == mdl);
+ assert(static_cast<int>((ymdl ).year()) == i + 2);
+ assert(ymdl.month_day_last() == mdl);
+ assert(static_cast<int>((ymdl -= years{1}).year()) == i + 1);
+ assert(ymdl.month_day_last() == mdl);
+ assert(static_cast<int>((ymdl ).year()) == i + 1);
+ assert(ymdl.month_day_last() == mdl);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/year.pass.cpp
new file mode 100644
index 000000000000..0f4da09dc89e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/year.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr chrono::day day() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().year());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<const year_month_day_last>().year()));
+
+ for (int i = 1; i <= 50; ++i)
+ {
+ year_month_day_last ym(year{i}, month_day_last{month{}});
+ assert( static_cast<int>(ym.year()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..d4e4a1185a96
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept;
+// Returns: x.year() == y.year() && x.month_day_last() == y.month_day_last().
+//
+// constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept;
+// Returns:
+// If x.year() < y.year(), returns true.
+// Otherwise, if x.year() > y.year(), returns false.
+// Otherwise, returns x.month_day_last() < y.month_day_last()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+
+ AssertComparisons6AreNoexcept<year_month_day_last>();
+ AssertComparisons6ReturnBool<year_month_day_last>();
+
+ constexpr month January = std::chrono::January;
+ constexpr month February = std::chrono::February;
+
+ static_assert( testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{January}},
+ year_month_day_last{year{1234}, month_day_last{January}},
+ true, false), "");
+
+// different month
+ static_assert( testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{January}},
+ year_month_day_last{year{1234}, month_day_last{February}},
+ false, true), "");
+
+// different year
+ static_assert( testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{January}},
+ year_month_day_last{year{1235}, month_day_last{January}},
+ false, true), "");
+
+// different month
+ static_assert( testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{January}},
+ year_month_day_last{year{1234}, month_day_last{February}},
+ false, true), "");
+
+// different year and month
+ static_assert( testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{February}},
+ year_month_day_last{year{1235}, month_day_last{January}},
+ false, true), "");
+
+// same year, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons6(
+ year_month_day_last{year{1234}, month_day_last{month{i}}},
+ year_month_day_last{year{1234}, month_day_last{month{j}}},
+ i == j, i < j )));
+
+// same month, different years
+ for (int i = 1000; i < 20; ++i)
+ for (int j = 1000; j < 20; ++j)
+ assert((testComparisons6(
+ year_month_day_last{year{i}, month_day_last{January}},
+ year_month_day_last{year{j}, month_day_last{January}},
+ i == j, i < j )));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..1c8d4e7afd9e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last
+// operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
+//
+// Returns: ymdl + (-dm).
+//
+// constexpr year_month_day_last
+// operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
+//
+// Returns: ymdl + (-dy).
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+constexpr bool testConstexprYears (std::chrono::year_month_day_last ymdl)
+{
+ std::chrono::year_month_day_last ym1 = ymdl - std::chrono::years{10};
+ return
+ ym1.year() == std::chrono::year{static_cast<int>(ymdl.year()) - 10}
+ && ym1.month() == ymdl.month()
+ ;
+}
+
+constexpr bool testConstexprMonths (std::chrono::year_month_day_last ymdl)
+{
+ std::chrono::year_month_day_last ym1 = ymdl - std::chrono::months{6};
+ return
+ ym1.year() == ymdl.year()
+ && ym1.month() == std::chrono::month{static_cast<unsigned>(ymdl.month()) - 6}
+ ;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using months = std::chrono::months;
+ using years = std::chrono::years;
+
+ constexpr month December = std::chrono::December;
+
+ { // year_month_day_last - years
+ ASSERT_NOEXCEPT( std::declval<year_month_day_last>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<year_month_day_last>() - std::declval<years>()));
+
+ static_assert(testConstexprYears(year_month_day_last{year{1234}, month_day_last{December}}), "");
+ year_month_day_last ym{year{1234}, month_day_last{December}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_day_last ym1 = ym - years{i};
+ assert(static_cast<int>(ym1.year()) == 1234 - i);
+ assert(ym1.month() == December);
+ }
+ }
+
+ { // year_month_day_last - months
+ ASSERT_NOEXCEPT( std::declval<year_month_day_last>() - std::declval<months>());
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<year_month_day_last>() - std::declval<months>()));
+
+ static_assert(testConstexprMonths(year_month_day_last{year{1234}, month_day_last{December}}), "");
+// TODO test wrapping
+ year_month_day_last ym{year{1234}, month_day_last{December}};
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year_month_day_last ym1 = ym - months{i};
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(static_cast<unsigned>(ym1.month()) == 12U-i);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..25ab85d8ff5f
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr year_month_day_last
+// operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
+//
+// Returns: (ymdl.year() / ymdl.month() + dm) / last.
+//
+// constexpr year_month_day_last
+// operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
+//
+// Returns: ymdl + dm.
+//
+//
+// constexpr year_month_day_last
+// operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
+//
+// Returns: {ymdl.year()+dy, ymdl.month_day_last()}.
+//
+// constexpr year_month_day_last
+// operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
+//
+// Returns: ymdl + dy
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool testConstexprYears(std::chrono::year_month_day_last ymdl)
+{
+ std::chrono::years offset{23};
+ if (static_cast<int>((ymdl ).year()) != 1) return false;
+ if (static_cast<int>((ymdl + offset).year()) != 24) return false;
+ if ( (ymdl + offset).month() != ymdl.month()) return false;
+ if (static_cast<int>((offset + ymdl).year()) != 24) return false;
+ if ( (offset + ymdl).month() != ymdl.month()) return false;
+ return true;
+}
+
+
+constexpr bool testConstexprMonths(std::chrono::year_month_day_last ymdl)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ymdl ).month()) != 1) return false;
+ if ( (ymdl + offset).year() != ymdl.year()) return false;
+ if (static_cast<unsigned>((ymdl + offset).month()) != 7) return false;
+ if (static_cast<unsigned>((offset + ymdl).month()) != 7) return false;
+ if ( (offset + ymdl).year() != ymdl.year()) return false;
+ return true;
+}
+
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using months = std::chrono::months;
+ using years = std::chrono::years;
+
+ constexpr month January = std::chrono::January;
+
+ { // year_month_day_last + months
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month_day_last>());
+
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<year_month_day_last>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<months>() + std::declval<year_month_day_last>()));
+
+ static_assert(testConstexprMonths(year_month_day_last{year{1}, month_day_last{January}}), "");
+
+ year_month_day_last ym{year{1234}, month_day_last{January}};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month_day_last ym1 = ym + months{i};
+ year_month_day_last ym2 = months{i} + ym;
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(static_cast<int>(ym2.year()) == 1234);
+ assert(ym1.month() == month(1 + i));
+ assert(ym2.month() == month(1 + i));
+ assert(ym1 == ym2);
+ }
+ }
+
+ { // year_month_day_last + years
+ ASSERT_NOEXCEPT(std::declval<year_month_day_last>() + std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month_day_last>());
+
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<year_month_day_last>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_day_last, decltype(std::declval<years>() + std::declval<year_month_day_last>()));
+
+ static_assert(testConstexprYears(year_month_day_last{year{1}, month_day_last{January}}), "");
+
+ year_month_day_last ym{year{1234}, month_day_last{January}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_day_last ym1 = ym + years{i};
+ year_month_day_last ym2 = years{i} + ym;
+ assert(static_cast<int>(ym1.year()) == i + 1234);
+ assert(static_cast<int>(ym2.year()) == i + 1234);
+ assert(ym1.month() == std::chrono::January);
+ assert(ym2.month() == std::chrono::January);
+ assert(ym1 == ym2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..06c752e2905c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year_month_day_last;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);
+//
+// Returns: os << ymdl.year() << '/' << ymdl.month_day_last().
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using month_day_last = std::chrono::month_day_last;
+
+ std::cout << year_month_day_last{year{2018}, month_day_last{month{3}}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp
new file mode 100644
index 000000000000..a0b98abb7ddf
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// explicit constexpr year_month_weekday(const local_days& dp) noexcept;
+//
+//
+// Effects: Constructs an object of type year_month_weekday that corresponds
+// to the date represented by dp
+//
+// Remarks: Equivalent to constructing with sys_days{dp.time_since_epoch()}.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::day day() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using days = std::chrono::days;
+ using local_days = std::chrono::local_days;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT(year_month_weekday{std::declval<const local_days>()});
+
+ {
+ constexpr local_days sd{}; // 1-Jan-1970 was a Thursday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{1970}, "");
+ static_assert( ymwd.month() == std::chrono::January, "");
+ static_assert( ymwd.weekday() == std::chrono::Thursday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Thursday, 1}, "");
+ static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip
+ }
+
+ {
+ constexpr local_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{2000}, "");
+ static_assert( ymwd.month() == std::chrono::February, "");
+ static_assert( ymwd.weekday() == std::chrono::Wednesday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 1}, "");
+ static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip
+ }
+
+
+ {
+ constexpr local_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{1940}, "");
+ static_assert( ymwd.month() == std::chrono::January, "");
+ static_assert( ymwd.weekday() == std::chrono::Tuesday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Tuesday, 1}, "");
+ static_assert( ymwd == year_month_weekday{local_days{ymwd}}, ""); // round trip
+ }
+
+ {
+ local_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
+ year_month_weekday ymwd{sd};
+
+ assert( ymwd.ok());
+ assert( ymwd.year() == year{1939});
+ assert( ymwd.month() == std::chrono::November);
+ assert( ymwd.weekday() == std::chrono::Wednesday);
+ assert( ymwd.index() == 5);
+ assert((ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 5}));
+ assert( ymwd == year_month_weekday{local_days{ymwd}}); // round trip
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.pass.cpp
new file mode 100644
index 000000000000..751de609177e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// year_month_weekday() = default;
+// constexpr year_month_weekday(const chrono::year& y, const chrono::month& m,
+// const chrono::weekday_indexed& wdi) noexcept;
+//
+// Effects: Constructs an object of type year_month_weekday by initializing
+// y_ with y, m_ with m, and wdi_ with wdi.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::weekday weekday() const noexcept;
+// constexpr unsigned index() const noexcept;
+// constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT(year_month_weekday{});
+ ASSERT_NOEXCEPT(year_month_weekday{year{1}, month{1}, weekday_indexed{Tuesday, 1}});
+
+ constexpr year_month_weekday ym0{};
+ static_assert( ym0.year() == year{}, "");
+ static_assert( ym0.month() == month{}, "");
+ static_assert( ym0.weekday() == weekday{}, "");
+ static_assert( ym0.index() == 0, "");
+ static_assert( ym0.weekday_indexed() == weekday_indexed{}, "");
+ static_assert(!ym0.ok(), "");
+
+ constexpr year_month_weekday ym1{year{2019}, January, weekday_indexed{Tuesday, 1}};
+ static_assert( ym1.year() == year{2019}, "");
+ static_assert( ym1.month() == January, "");
+ static_assert( ym1.weekday() == Tuesday, "");
+ static_assert( ym1.index() == 1, "");
+ static_assert( ym1.weekday_indexed() == weekday_indexed{Tuesday, 1}, "");
+ static_assert( ym1.ok(), "");
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp
new file mode 100644
index 000000000000..b9d3b6c62b1c
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday(const sys_days& dp) noexcept;
+//
+// Effects: Constructs an object of type year_month_weekday that corresponds
+// to the date represented by dp
+//
+// Remarks: For any value ymd of type year_month_weekday for which ymd.ok() is true,
+// ymd == year_month_weekday{sys_days{ymd}} is true.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using days = std::chrono::days;
+ using sys_days = std::chrono::sys_days;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT(year_month_weekday{std::declval<const sys_days>()});
+
+ {
+ constexpr sys_days sd{}; // 1-Jan-1970 was a Thursday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{1970}, "");
+ static_assert( ymwd.month() == std::chrono::January, "");
+ static_assert( ymwd.weekday() == std::chrono::Thursday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Thursday, 1}, "");
+ static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip
+ }
+
+ {
+ constexpr sys_days sd{days{10957+32}}; // 2-Feb-2000 was a Wednesday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{2000}, "");
+ static_assert( ymwd.month() == std::chrono::February, "");
+ static_assert( ymwd.weekday() == std::chrono::Wednesday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 1}, "");
+ static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip
+ }
+
+
+ {
+ constexpr sys_days sd{days{-10957}}; // 2-Jan-1940 was a Tuesday
+ constexpr year_month_weekday ymwd{sd};
+
+ static_assert( ymwd.ok(), "");
+ static_assert( ymwd.year() == year{1940}, "");
+ static_assert( ymwd.month() == std::chrono::January, "");
+ static_assert( ymwd.weekday() == std::chrono::Tuesday, "");
+ static_assert( ymwd.index() == 1, "");
+ static_assert( ymwd.weekday_indexed() == weekday_indexed{std::chrono::Tuesday, 1}, "");
+ static_assert( ymwd == year_month_weekday{sys_days{ymwd}}, ""); // round trip
+ }
+
+ {
+ sys_days sd{days{-(10957+34)}}; // 29-Nov-1939 was a Wednesday
+ year_month_weekday ymwd{sd};
+
+ assert( ymwd.ok());
+ assert( ymwd.year() == year{1939});
+ assert( ymwd.month() == std::chrono::November);
+ assert( ymwd.weekday() == std::chrono::Wednesday);
+ assert( ymwd.index() == 5);
+ assert((ymwd.weekday_indexed() == weekday_indexed{std::chrono::Wednesday, 5}));
+ assert( ymwd == year_month_weekday{sys_days{ymwd}}); // round trip
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/index.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/index.pass.cpp
new file mode 100644
index 000000000000..5a29b8218034
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/index.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr unsigned index() const noexcept;
+// Returns: wdi_.index()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().index());
+ ASSERT_SAME_TYPE(unsigned, decltype(std::declval<const year_month_weekday>().index()));
+
+ static_assert( year_month_weekday{}.index() == 0, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday ymwd0(year{1234}, month{2}, weekday_indexed{weekday{2}, i});
+ assert(ymwd0.index() == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/month.pass.cpp
new file mode 100644
index 000000000000..5749da9af7e5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/month.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const year_month_weekday>().month()));
+
+ static_assert( year_month_weekday{}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday ymd(year{1234}, month{i}, weekday_indexed{});
+ assert( static_cast<unsigned>(ymd.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ok.pass.cpp
new file mode 100644
index 000000000000..97f898986be0
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ok.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr bool ok() const noexcept;
+// Returns: m_.ok() && y_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year_month_weekday>().ok()));
+
+ static_assert(!year_month_weekday{}.ok(), "");
+
+ static_assert(!year_month_weekday{year{-32768}, month{}, weekday_indexed{}}.ok(), ""); // All three bad
+
+ static_assert(!year_month_weekday{year{-32768}, January, weekday_indexed{Tuesday, 1}}.ok(), ""); // Bad year
+ static_assert(!year_month_weekday{year{2019}, month{}, weekday_indexed{Tuesday, 1}}.ok(), ""); // Bad month
+ static_assert(!year_month_weekday{year{2019}, January, weekday_indexed{} }.ok(), ""); // Bad day
+
+ static_assert(!year_month_weekday{year{-32768}, month{}, weekday_indexed{Tuesday, 1}}.ok(), ""); // Bad year & month
+ static_assert(!year_month_weekday{year{2019}, month{}, weekday_indexed{} }.ok(), ""); // Bad month & day
+ static_assert(!year_month_weekday{year{-32768}, January, weekday_indexed{} }.ok(), ""); // Bad year & day
+
+ static_assert( year_month_weekday{year{2019}, January, weekday_indexed{Tuesday, 1}}.ok(), ""); // All OK
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday ym{year{2019}, January, weekday_indexed{Tuesday, i}};
+ assert((ym.ok() == weekday_indexed{Tuesday, i}.ok()));
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday ym{year{2019}, January, weekday_indexed{weekday{i}, 1}};
+ assert((ym.ok() == weekday_indexed{weekday{i}, 1}.ok()));
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday ym{year{2019}, month{i}, weekday_indexed{Tuesday, 1}};
+ assert((ym.ok() == month{i}.ok()));
+ }
+
+ const int ymax = static_cast<int>(year::max());
+ for (int i = ymax - 100; i <= ymax + 100; ++i)
+ {
+ year_month_weekday ym{year{i}, January, weekday_indexed{Tuesday, 1}};
+ assert((ym.ok() == year{i}.ok()));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp
new file mode 100644
index 000000000000..ef30ce526c65
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.local_days.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// explicit constexpr operator local_days() const noexcept;
+//
+// Returns: If y_.ok() && m_.ok() && wdi_.weekday().ok(), returns a
+// sys_days that represents the date (index() - 1) * 7 days after the first
+// weekday() of year()/month(). If index() is 0 the returned sys_days
+// represents the date 7 days prior to the first weekday() of
+// year()/month(). Otherwise the returned value is unspecified.
+//
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT(local_days(std::declval<year_month_weekday>()));
+
+ {
+ constexpr year_month_weekday ymwd{year{1970}, month{1}, weekday_indexed{std::chrono::Thursday, 1}};
+ constexpr local_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{0}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+ {
+ constexpr year_month_weekday ymwd{year{2000}, month{2}, weekday_indexed{std::chrono::Wednesday, 1}};
+ constexpr local_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{10957+32}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr year_month_weekday ymwd{year{1940}, month{1},weekday_indexed{std::chrono::Tuesday, 1}};
+ constexpr local_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{-10957}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+ {
+ year_month_weekday ymwd{year{1939}, month{11}, weekday_indexed{std::chrono::Wednesday, 5}};
+ local_days sd{ymwd};
+
+ assert( sd.time_since_epoch() == days{-(10957+34)});
+ assert( year_month_weekday{sd} == ymwd); // and back
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp
new file mode 100644
index 000000000000..04986e50d3f1
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/op.sys_days.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr operator sys_days() const noexcept;
+//
+// Returns: If y_.ok() && m_.ok() && wdi_.weekday().ok(), returns a
+// sys_days that represents the date (index() - 1) * 7 days after the first
+// weekday() of year()/month(). If index() is 0 the returned sys_days
+// represents the date 7 days prior to the first weekday() of
+// year()/month(). Otherwise the returned value is unspecified.
+//
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT(sys_days(std::declval<year_month_weekday>()));
+
+ {
+ constexpr year_month_weekday ymwd{year{1970}, month{1}, weekday_indexed{std::chrono::Thursday, 1}};
+ constexpr sys_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{0}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+ {
+ constexpr year_month_weekday ymwd{year{2000}, month{2}, weekday_indexed{std::chrono::Wednesday, 1}};
+ constexpr sys_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{10957+32}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+// There's one more leap day between 1/1/40 and 1/1/70
+// when compared to 1/1/70 -> 1/1/2000
+ {
+ constexpr year_month_weekday ymwd{year{1940}, month{1},weekday_indexed{std::chrono::Tuesday, 1}};
+ constexpr sys_days sd{ymwd};
+
+ static_assert( sd.time_since_epoch() == days{-10957}, "");
+ static_assert( year_month_weekday{sd} == ymwd, ""); // and back
+ }
+
+ {
+ year_month_weekday ymwd{year{1939}, month{11}, weekday_indexed{std::chrono::Wednesday, 5}};
+ sys_days sd{ymwd};
+
+ assert( sd.time_since_epoch() == days{-(10957+34)});
+ assert( year_month_weekday{sd} == ymwd); // and back
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp
new file mode 100644
index 000000000000..c5e101250a31
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday& operator+=(const months& m) noexcept;
+// constexpr year_month_weekday& operator-=(const months& m) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<unsigned>((d1 ).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 1}).month()) != 2) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 2}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 += Ds{12}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 1}).month()) != 3) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 2}).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 -= Ds{12}).month()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using months = std::chrono::months;
+
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday&>() += std::declval<months>());
+ ASSERT_SAME_TYPE(year_month_weekday&, decltype(std::declval<year_month_weekday&>() += std::declval<months>()));
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday&>() -= std::declval<months>());
+ ASSERT_SAME_TYPE(year_month_weekday&, decltype(std::declval<year_month_weekday&>() -= std::declval<months>()));
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ static_assert(testConstexpr<year_month_weekday, months>(year_month_weekday{year{1234}, month{1}, weekday_indexed{Tuesday, 2}}), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year y{1234};
+ year_month_weekday ymwd(y, month{i}, weekday_indexed{Tuesday, 2});
+
+ assert(static_cast<unsigned>((ymwd += months{2}).month()) == i + 2);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<unsigned>((ymwd ).month()) == i + 2);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<unsigned>((ymwd -= months{1}).month()) == i + 1);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<unsigned>((ymwd ).month()) == i + 1);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_year.pass.cpp
new file mode 100644
index 000000000000..86830249e707
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_year.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday& operator+=(const years& d) noexcept;
+// constexpr year_month_weekday& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<int>((d1 ).year()) != 1) return false;
+ if (static_cast<int>((d1 += Ds{ 1}).year()) != 2) return false;
+ if (static_cast<int>((d1 += Ds{ 2}).year()) != 4) return false;
+ if (static_cast<int>((d1 += Ds{12}).year()) != 16) return false;
+ if (static_cast<int>((d1 -= Ds{ 1}).year()) != 15) return false;
+ if (static_cast<int>((d1 -= Ds{ 2}).year()) != 13) return false;
+ if (static_cast<int>((d1 -= Ds{12}).year()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday&>() += std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_weekday&, decltype(std::declval<year_month_weekday&>() += std::declval<years>()));
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday&>() -= std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_weekday&, decltype(std::declval<year_month_weekday&>() -= std::declval<years>()));
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month January = std::chrono::January;
+
+ static_assert(testConstexpr<year_month_weekday, years>(year_month_weekday{year{1}, January, weekday_indexed{Tuesday, 2}}), "");
+
+ for (int i = 1000; i <= 1010; ++i)
+ {
+ year_month_weekday ymwd(year{i}, January, weekday_indexed{Tuesday, 2});
+
+ assert(static_cast<int>((ymwd += years{2}).year()) == i + 2);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<int>((ymwd ).year()) == i + 2);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<int>((ymwd -= years{1}).year()) == i + 1);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+
+ assert(static_cast<int>((ymwd ).year()) == i + 1);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+ assert(ymwd.index() == 2);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday.pass.cpp
new file mode 100644
index 000000000000..ad9bc6ee6121
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr chrono::weekday weekday() const noexcept;
+// Returns: wdi_.weekday()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().weekday());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<const year_month_weekday>().weekday()));
+
+ static_assert( year_month_weekday{}.weekday() == weekday{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday ymwd0(year{1234}, month{2}, weekday_indexed{weekday{i}, 1});
+ assert(static_cast<unsigned>(ymwd0.weekday()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday_indexed.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday_indexed.pass.cpp
new file mode 100644
index 000000000000..52d918e55c48
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday_indexed.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().weekday_indexed());
+ ASSERT_SAME_TYPE(weekday_indexed, decltype(std::declval<const year_month_weekday>().weekday_indexed()));
+
+ static_assert( year_month_weekday{}.weekday_indexed() == weekday_indexed{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday ymwd0(year{1234}, month{2}, weekday_indexed{weekday{i}, 1});
+ assert( static_cast<unsigned>(ymwd0.weekday_indexed().weekday()) == i);
+ assert( static_cast<unsigned>(ymwd0.weekday_indexed().index()) == 1);
+ year_month_weekday ymwd1(year{1234}, month{2}, weekday_indexed{weekday{2}, i});
+ assert( static_cast<unsigned>(ymwd1.weekday_indexed().weekday()) == 2);
+ assert( static_cast<unsigned>(ymwd1.weekday_indexed().index()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/year.pass.cpp
new file mode 100644
index 000000000000..5cf1cbaf7414
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/year.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr chrono::year year() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday>().year());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<const year_month_weekday>().year()));
+
+ static_assert( year_month_weekday{}.year() == year{}, "");
+
+ for (int i = 1; i <= 50; ++i)
+ {
+ year_month_weekday ym(year{i}, month{1}, weekday_indexed{});
+ assert( static_cast<int>(ym.year()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..fc13709cde08
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept;
+// Returns: x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()
+//
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using weekday = std::chrono::weekday;
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ AssertComparisons2AreNoexcept<year_month_weekday>();
+ AssertComparisons2ReturnBool<year_month_weekday>();
+
+ constexpr month January = std::chrono::January;
+ constexpr month February = std::chrono::February;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ true), "");
+
+// different day
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 2}},
+ false), "");
+
+// different month
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1234}, February, weekday_indexed{Tuesday, 1}},
+ false), "");
+
+// different year
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1235}, January, weekday_indexed{Tuesday, 1}},
+ false), "");
+
+
+// different month and day
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1234}, February, weekday_indexed{Tuesday, 2}},
+ false), "");
+
+// different year and month
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, February, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1235}, January, weekday_indexed{Tuesday, 1}},
+ false), "");
+
+// different year and day
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, 2}},
+ year_month_weekday{year{1235}, January, weekday_indexed{Tuesday, 1}},
+ false), "");
+
+// different year, month and day
+ static_assert( testComparisons2(
+ year_month_weekday{year{1234}, February, weekday_indexed{Tuesday, 2}},
+ year_month_weekday{year{1235}, January, weekday_indexed{Tuesday, 1}},
+ false), "");
+
+
+// same year, different days
+ for (unsigned i = 1; i < 28; ++i)
+ for (unsigned j = 1; j < 28; ++j)
+ assert((testComparisons2(
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, i}},
+ year_month_weekday{year{1234}, January, weekday_indexed{Tuesday, j}},
+ i == j)));
+
+// same year, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons2(
+ year_month_weekday{year{1234}, month{i}, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{1234}, month{j}, weekday_indexed{Tuesday, 1}},
+ i == j)));
+
+// same month, different years
+ for (int i = 1000; i < 20; ++i)
+ for (int j = 1000; j < 20; ++j)
+ assert((testComparisons2(
+ year_month_weekday{year{i}, January, weekday_indexed{Tuesday, 1}},
+ year_month_weekday{year{j}, January, weekday_indexed{Tuesday, 1}},
+ i == j)));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..0b217414ca93
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
+// Returns: ymwd + (-dm).
+//
+// constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
+// Returns: ymwd + (-dy).
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+constexpr bool testConstexprYears ()
+{
+ std::chrono::year_month_weekday ym0{std::chrono::year{1234}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::Tuesday, 1}};
+ std::chrono::year_month_weekday ym1 = ym0 - std::chrono::years{10};
+ return
+ ym1.year() == std::chrono::year{1234-10}
+ && ym1.month() == std::chrono::January
+ && ym1.weekday() == std::chrono::Tuesday
+ && ym1.index() == 1
+ ;
+}
+
+constexpr bool testConstexprMonths ()
+{
+ std::chrono::year_month_weekday ym0{std::chrono::year{1234}, std::chrono::November, std::chrono::weekday_indexed{std::chrono::Tuesday, 1}};
+ std::chrono::year_month_weekday ym1 = ym0 - std::chrono::months{6};
+ return
+ ym1.year() == std::chrono::year{1234}
+ && ym1.month() == std::chrono::May
+ && ym1.weekday() == std::chrono::Tuesday
+ && ym1.index() == 1
+ ;
+}
+
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using years = std::chrono::years;
+ using months = std::chrono::months;
+
+ constexpr month November = std::chrono::November;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ { // year_month_weekday - years
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<year_month_weekday>() - std::declval<years>()));
+
+ static_assert(testConstexprYears(), "");
+
+ year_month_weekday ym{year{1234}, November, weekday_indexed{Tuesday, 1}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_weekday ym1 = ym - years{i};
+ assert(static_cast<int>(ym1.year()) == 1234 - i);
+ assert(ym1.month() == November);
+ assert(ym1.weekday() == Tuesday);
+ assert(ym1.index() == 1);
+ }
+ }
+
+ { // year_month_weekday - months
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday>() - std::declval<months>());
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<year_month_weekday>() - std::declval<months>()));
+
+ static_assert(testConstexprMonths(), "");
+
+ year_month_weekday ym{year{1234}, November, weekday_indexed{Tuesday, 2}};
+ for (unsigned i = 1; i <= 10; ++i)
+ {
+ year_month_weekday ym1 = ym - months{i};
+ assert(ym1.year() == year{1234});
+ assert(ym1.month() == month{11-i});
+ assert(ym1.weekday() == Tuesday);
+ assert(ym1.index() == 2);
+ }
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..50572c0c4968
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/plus.pass.cpp
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+// constexpr year_month_weekday operator+(const year_month_weekday& ymd, const months& dm) noexcept;
+// Returns: (ymd.year() / ymd.month() + dm) / ymd.day().
+//
+// constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymd) noexcept;
+// Returns: ymd + dm.
+//
+//
+// constexpr year_month_weekday operator+(const year_month_weekday& ymd, const years& dy) noexcept;
+// Returns: (ymd.year() + dy) / ymd.month() / ymd.day().
+//
+// constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymd) noexcept;
+// Returns: ym + dm.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool testConstexprYears(std::chrono::year_month_weekday ym)
+{
+ std::chrono::years offset{23};
+ if (static_cast<int>((ym ).year()) != 1) return false;
+ if (static_cast<int>((ym + offset).year()) != 24) return false;
+ if (static_cast<int>((offset + ym).year()) != 24) return false;
+ return true;
+}
+
+
+constexpr bool testConstexprMonths(std::chrono::year_month_weekday ym)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ym ).month()) != 1) return false;
+ if (static_cast<unsigned>((ym + offset).month()) != 7) return false;
+ if (static_cast<unsigned>((offset + ym).month()) != 7) return false;
+ return true;
+}
+
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_indexed = std::chrono::weekday_indexed;
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using years = std::chrono::years;
+ using months = std::chrono::months;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month January = std::chrono::January;
+
+ { // year_month_weekday + months (and switched)
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month_weekday>());
+
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<year_month_weekday>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<months>() + std::declval<year_month_weekday>()));
+
+ static_assert(testConstexprMonths(year_month_weekday{year{1}, January, weekday_indexed{Tuesday, 1}}), "");
+
+ year_month_weekday ym{year{1234}, January, weekday_indexed{Tuesday, 3}};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month_weekday ym1 = ym + months{i};
+ year_month_weekday ym2 = months{i} + ym;
+ assert(static_cast<int>(ym1.year()) == 1234);
+ assert(static_cast<int>(ym2.year()) == 1234);
+ assert(ym1.month() == month(1 + i));
+ assert(ym2.month() == month(1 + i));
+ assert(ym1.weekday() == Tuesday);
+ assert(ym2.weekday() == Tuesday);
+ assert(ym1.index() == 3);
+ assert(ym2.index() == 3);
+ assert(ym1 == ym2);
+ }
+ }
+
+ { // year_month_weekday + years (and switched)
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday>() + std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month_weekday>());
+
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<year_month_weekday>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_weekday, decltype(std::declval<years>() + std::declval<year_month_weekday>()));
+
+ static_assert(testConstexprYears (year_month_weekday{year{1}, January, weekday_indexed{Tuesday, 1}}), "");
+
+ year_month_weekday ym{year{1234}, std::chrono::January, weekday_indexed{Tuesday, 3}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_weekday ym1 = ym + years{i};
+ year_month_weekday ym2 = years{i} + ym;
+ assert(static_cast<int>(ym1.year()) == i + 1234);
+ assert(static_cast<int>(ym2.year()) == i + 1234);
+ assert(ym1.month() == January);
+ assert(ym2.month() == January);
+ assert(ym1.weekday() == Tuesday);
+ assert(ym2.weekday() == Tuesday);
+ assert(ym1.index() == 3);
+ assert(ym2.index() == 3);
+ assert(ym1 == ym2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..f985f46ea3d5
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year_month_weekday;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ym);
+//
+// Returns: os << ym.year() << '/' << ym.month().
+//
+//
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const year_month_weekday& ym);
+//
+// Effects: Streams ym into os using the format specified by the NTCTS fmt. fmt encoding follows the rules specified in 25.11.
+//
+// template<class charT, class traits, class Alloc = allocator<charT>>
+// basic_istream<charT, traits>&
+// from_stream(basic_istream<charT, traits>& is, const charT* fmt,
+// year_month_weekday& ym, basic_string<charT, traits, Alloc>* abbrev = nullptr,
+// minutes* offset = nullptr);
+//
+// Effects: Attempts to parse the input stream is into the year_month_weekday ym using the format
+// flags given in the NTCTS fmt as specified in 25.12. If the parse fails to decode
+// a valid year_month_weekday, is.setstate(ios_- base::failbit) shall be called and ym shall
+// not be modified. If %Z is used and successfully parsed, that value will be assigned
+// to *abbrev if abbrev is non-null. If %z (or a modified variant) is used and
+// successfully parsed, that value will be assigned to *offset if offset is non-null.
+
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_weekday = std::chrono::year_month_weekday;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+
+ std::cout << year_month_weekday{year{2018}, month{3}, weekday{4}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwd/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/types.pass.cpp
new file mode 100644
index 000000000000..8969bd32ac46
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwd/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_weekday = std::chrono::year_month_weekday;
+
+ static_assert(std::is_trivially_copyable_v<year_month_weekday>, "");
+ static_assert(std::is_standard_layout_v<year_month_weekday>, "");
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ctor.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ctor.pass.cpp
new file mode 100644
index 000000000000..cd3f112acc55
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ctor.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m,
+// const chrono::weekday_last& wdl) noexcept;
+//
+// Effects: Constructs an object of type year_month_weekday_last by initializing
+// y_ with y, m_ with m, and wdl_ with wdl.
+//
+// constexpr chrono::year year() const noexcept;
+// constexpr chrono::month month() const noexcept;
+// constexpr chrono::weekday weekday() const noexcept;
+// constexpr chrono::weekday_last weekday_last() const noexcept;
+// constexpr bool ok() const noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT(year_month_weekday_last{year{1}, month{1}, weekday_last{Tuesday}});
+
+ constexpr year_month_weekday_last ym1{year{2019}, January, weekday_last{Tuesday}};
+ static_assert( ym1.year() == year{2019}, "");
+ static_assert( ym1.month() == January, "");
+ static_assert( ym1.weekday() == Tuesday, "");
+ static_assert( ym1.weekday_last() == weekday_last{Tuesday}, "");
+ static_assert( ym1.ok(), "");
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/month.pass.cpp
new file mode 100644
index 000000000000..f0c7ec4887dd
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/month.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr chrono::month month() const noexcept;
+// Returns: wd_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday_last>().month());
+ ASSERT_SAME_TYPE(month, decltype(std::declval<const year_month_weekday_last>().month()));
+
+ static_assert( year_month_weekday_last{year{}, month{}, weekday_last{weekday{}}}.month() == month{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday_last ymd(year{1234}, month{i}, weekday_last{weekday{}});
+ assert( static_cast<unsigned>(ymd.month()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ok.pass.cpp
new file mode 100644
index 000000000000..d9443d34b191
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ok.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr bool ok() const noexcept;
+// Returns: y_.ok() && m_.ok() && wdl_.ok().
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday_last>().ok());
+ ASSERT_SAME_TYPE(bool, decltype(std::declval<const year_month_weekday_last>().ok()));
+
+ static_assert(!year_month_weekday_last{year{-32768}, month{}, weekday_last{weekday{}}}.ok(), ""); // All three bad
+
+ static_assert(!year_month_weekday_last{year{-32768}, January, weekday_last{Tuesday}}.ok(), ""); // Bad year
+ static_assert(!year_month_weekday_last{year{2019}, month{}, weekday_last{Tuesday}}.ok(), ""); // Bad month
+ static_assert(!year_month_weekday_last{year{2019}, January, weekday_last{weekday{7}}}.ok(), ""); // Bad day
+
+ static_assert(!year_month_weekday_last{year{-32768}, month{}, weekday_last{Tuesday}}.ok(), ""); // Bad year & month
+ static_assert(!year_month_weekday_last{year{2019}, month{}, weekday_last{weekday{7}}}.ok(), ""); // Bad month & day
+ static_assert(!year_month_weekday_last{year{-32768}, January, weekday_last{weekday{7}}}.ok(), ""); // Bad year & day
+
+ static_assert( year_month_weekday_last{year{2019}, January, weekday_last{Tuesday}}.ok(), ""); // All OK
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday_last ym{year{2019}, January, weekday_last{Tuesday}};
+ assert((ym.ok() == weekday_last{Tuesday}.ok()));
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday_last ym{year{2019}, January, weekday_last{weekday{i}}};
+ assert((ym.ok() == weekday_last{weekday{i}}.ok()));
+ }
+
+ for (unsigned i = 0; i <= 50; ++i)
+ {
+ year_month_weekday_last ym{year{2019}, month{i}, weekday_last{Tuesday}};
+ assert((ym.ok() == month{i}.ok()));
+ }
+
+ const int ymax = static_cast<int>(year::max());
+ for (int i = ymax - 100; i <= ymax + 100; ++i)
+ {
+ year_month_weekday_last ym{year{i}, January, weekday_last{Tuesday}};
+ assert((ym.ok() == year{i}.ok()));
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp
new file mode 100644
index 000000000000..45f1ac4ae2d6
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_day_last;
+
+// constexpr operator local_days() const noexcept;
+// Returns: local_days{sys_days{*this}.time_since_epoch()}.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month_day_last = std::chrono::month_day_last;
+ using year_month_day_last = std::chrono::year_month_day_last;
+ using local_days = std::chrono::local_days;
+ using days = std::chrono::days;
+
+ ASSERT_NOEXCEPT( static_cast<local_days>(std::declval<const year_month_day_last>()));
+ ASSERT_SAME_TYPE(local_days, decltype(static_cast<local_days>(std::declval<const year_month_day_last>())));
+
+ { // Last day in Jan 1970 was the 31st
+ constexpr year_month_day_last ymdl{year{1970}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{2000}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{10957+30}, "");
+ }
+
+ {
+ constexpr year_month_day_last ymdl{year{1940}, month_day_last{std::chrono::January}};
+ constexpr local_days sd{ymdl};
+
+ static_assert(sd.time_since_epoch() == days{-10957+29}, "");
+ }
+
+ {
+ year_month_day_last ymdl{year{1939}, month_day_last{std::chrono::November}};
+ local_days sd{ymdl};
+
+ assert(sd.time_since_epoch() == days{-(10957+33)});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp
new file mode 100644
index 000000000000..c5abe4ace248
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr operator sys_days() const noexcept;
+// Returns: If ok() == true, returns a sys_days that represents the last weekday()
+// of year()/month(). Otherwise the returned value is unspecified.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using sys_days = std::chrono::sys_days;
+ using days = std::chrono::days;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ ASSERT_NOEXCEPT( static_cast<sys_days>(std::declval<const year_month_weekday_last>()));
+ ASSERT_SAME_TYPE(sys_days, decltype(static_cast<sys_days>(std::declval<const year_month_weekday_last>())));
+
+ constexpr month January = std::chrono::January;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ { // Last Tuesday in Jan 1970 was the 27th
+ constexpr year_month_weekday_last ymwdl{year{1970}, January, weekday_last{Tuesday}};
+ constexpr sys_days sd{ymwdl};
+
+ static_assert(sd.time_since_epoch() == days{26}, "");
+ }
+
+ { // Last Tuesday in Jan 2000 was the 25th
+ constexpr year_month_weekday_last ymwdl{year{2000}, January, weekday_last{Tuesday}};
+ constexpr sys_days sd{ymwdl};
+
+ static_assert(sd.time_since_epoch() == days{10957+24}, "");
+ }
+
+ { // Last Tuesday in Jan 1940 was the 30th
+ constexpr year_month_weekday_last ymwdl{year{1940}, January, weekday_last{Tuesday}};
+ constexpr sys_days sd{ymwdl};
+
+ static_assert(sd.time_since_epoch() == days{-10958+29}, "");
+ }
+
+ { // Last Tuesday in Nov 1939 was the 28th
+ year_month_weekday_last ymdl{year{1939}, std::chrono::November, weekday_last{Tuesday}};
+ sys_days sd{ymdl};
+
+ assert(sd.time_since_epoch() == days{-(10957+35)});
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_month.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_month.pass.cpp
new file mode 100644
index 000000000000..d416f6b2b34e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_month.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last& operator+=(const months& m) noexcept;
+// constexpr year_month_weekday_last& operator-=(const months& m) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<unsigned>((d1 ).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 1}).month()) != 2) return false;
+ if (static_cast<unsigned>((d1 += Ds{ 2}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 += Ds{12}).month()) != 4) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 1}).month()) != 3) return false;
+ if (static_cast<unsigned>((d1 -= Ds{ 2}).month()) != 1) return false;
+ if (static_cast<unsigned>((d1 -= Ds{12}).month()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using months = std::chrono::months;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last&>() += std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last&>() -= std::declval<months>());
+
+ ASSERT_SAME_TYPE(year_month_weekday_last&, decltype(std::declval<year_month_weekday_last&>() += std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_weekday_last&, decltype(std::declval<year_month_weekday_last&>() -= std::declval<months>()));
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ static_assert(testConstexpr<year_month_weekday_last, months>(year_month_weekday_last{year{1234}, month{1}, weekday_last{Tuesday}}), "");
+
+ for (unsigned i = 0; i <= 10; ++i)
+ {
+ year y{1234};
+ year_month_weekday_last ymwd(y, month{i}, weekday_last{Tuesday});
+
+ assert(static_cast<unsigned>((ymwd += months{2}).month()) == i + 2);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<unsigned>((ymwd ).month()) == i + 2);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<unsigned>((ymwd -= months{1}).month()) == i + 1);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<unsigned>((ymwd ).month()) == i + 1);
+ assert(ymwd.year() == y);
+ assert(ymwd.weekday() == Tuesday);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp
new file mode 100644
index 000000000000..8793c659ad3e
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last& operator+=(const years& d) noexcept;
+// constexpr year_month_weekday_last& operator-=(const years& d) noexcept;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <typename D, typename Ds>
+constexpr bool testConstexpr(D d1)
+{
+ if (static_cast<int>((d1 ).year()) != 1) return false;
+ if (static_cast<int>((d1 += Ds{ 1}).year()) != 2) return false;
+ if (static_cast<int>((d1 += Ds{ 2}).year()) != 4) return false;
+ if (static_cast<int>((d1 += Ds{12}).year()) != 16) return false;
+ if (static_cast<int>((d1 -= Ds{ 1}).year()) != 15) return false;
+ if (static_cast<int>((d1 -= Ds{ 2}).year()) != 13) return false;
+ if (static_cast<int>((d1 -= Ds{12}).year()) != 1) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using years = std::chrono::years;
+
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last&>() += std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last&>() -= std::declval<years>());
+
+ ASSERT_SAME_TYPE(year_month_weekday_last&, decltype(std::declval<year_month_weekday_last&>() += std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_weekday_last&, decltype(std::declval<year_month_weekday_last&>() -= std::declval<years>()));
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month January = std::chrono::January;
+
+ static_assert(testConstexpr<year_month_weekday_last, years>(year_month_weekday_last{year{1}, January, weekday_last{Tuesday}}), "");
+
+ for (int i = 1000; i <= 1010; ++i)
+ {
+ year_month_weekday_last ymwd(year{i}, January, weekday_last{Tuesday});
+
+ assert(static_cast<int>((ymwd += years{2}).year()) == i + 2);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<int>((ymwd ).year()) == i + 2);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<int>((ymwd -= years{1}).year()) == i + 1);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+
+ assert(static_cast<int>((ymwd ).year()) == i + 1);
+ assert(ymwd.month() == January);
+ assert(ymwd.weekday() == Tuesday);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/weekday.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/weekday.pass.cpp
new file mode 100644
index 000000000000..83640302fa34
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/weekday.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr chrono::weekday weekday() const noexcept;
+// Returns: wdi_.weekday()
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday_last>().weekday());
+ ASSERT_SAME_TYPE(weekday, decltype(std::declval<const year_month_weekday_last>().weekday()));
+
+ static_assert( year_month_weekday_last{year{}, month{}, weekday_last{weekday{}}}.weekday() == weekday{}, "");
+
+ for (unsigned i = 1; i <= 50; ++i)
+ {
+ year_month_weekday_last ymwdl(year{1}, month{1}, weekday_last{weekday{i}});
+ assert(static_cast<unsigned>(ymwdl.weekday()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/year.pass.cpp
new file mode 100644
index 000000000000..fb621afcdc02
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/year.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr chrono::year year() const noexcept;
+// Returns: d_
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ ASSERT_NOEXCEPT( std::declval<const year_month_weekday_last>().year());
+ ASSERT_SAME_TYPE(year, decltype(std::declval<const year_month_weekday_last>().year()));
+
+ static_assert( year_month_weekday_last{year{}, month{}, weekday_last{weekday{}}}.year() == year{}, "");
+
+ for (int i = 1; i <= 50; ++i)
+ {
+ year_month_weekday_last ymwdl(year{i}, month{1}, weekday_last{weekday{}});
+ assert(static_cast<int>(ymwdl.year()) == i);
+ }
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/comparisons.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/comparisons.pass.cpp
new file mode 100644
index 000000000000..6af54892a5b7
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/comparisons.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
+// Returns: x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last()
+//
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_comparisons.h"
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ AssertComparisons2AreNoexcept<year_month_weekday_last>();
+ AssertComparisons2ReturnBool<year_month_weekday_last>();
+
+ constexpr month January = std::chrono::January;
+ constexpr month February = std::chrono::February;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr weekday Wednesday = std::chrono::Wednesday;
+
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ true), "");
+
+// different day
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1234}, January, weekday_last{Wednesday}},
+ false), "");
+
+// different month
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1234}, February, weekday_last{Tuesday}},
+ false), "");
+
+// different year
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1235}, January, weekday_last{Tuesday}},
+ false), "");
+
+
+// different month and day
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1234}, February, weekday_last{Wednesday}},
+ false), "");
+
+// different year and month
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, February, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1235}, January, weekday_last{Tuesday}},
+ false), "");
+
+// different year and day
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{Wednesday}},
+ year_month_weekday_last{year{1235}, January, weekday_last{Tuesday}},
+ false), "");
+
+// different year, month and day
+ static_assert( testComparisons2(
+ year_month_weekday_last{year{1234}, February, weekday_last{Wednesday}},
+ year_month_weekday_last{year{1235}, January, weekday_last{Tuesday}},
+ false), "");
+
+
+// same year, different days
+ for (unsigned i = 1; i < 28; ++i)
+ for (unsigned j = 1; j < 28; ++j)
+ assert((testComparisons2(
+ year_month_weekday_last{year{1234}, January, weekday_last{weekday{i}}},
+ year_month_weekday_last{year{1234}, January, weekday_last{weekday{j}}},
+ i == j)));
+
+// same year, different months
+ for (unsigned i = 1; i < 12; ++i)
+ for (unsigned j = 1; j < 12; ++j)
+ assert((testComparisons2(
+ year_month_weekday_last{year{1234}, month{i}, weekday_last{Tuesday}},
+ year_month_weekday_last{year{1234}, month{j}, weekday_last{Tuesday}},
+ i == j)));
+
+// same month, different years
+ for (int i = 1000; i < 20; ++i)
+ for (int j = 1000; j < 20; ++j)
+ assert((testComparisons2(
+ year_month_weekday_last{year{i}, January, weekday_last{Tuesday}},
+ year_month_weekday_last{year{j}, January, weekday_last{Tuesday}},
+ i == j)));
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/minus.pass.cpp
new file mode 100644
index 000000000000..c0ca34e83fcc
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/minus.pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
+// Returns: ymwdl + (-dm).
+//
+// constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
+// Returns: ymwdl + (-dy).
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include <iostream>
+
+constexpr bool testConstexprYears(std::chrono::year_month_weekday_last ym)
+{
+ std::chrono::years offset{14};
+ if (static_cast<int>((ym ).year()) != 66) return false;
+ if (static_cast<int>((ym - offset).year()) != 52) return false;
+ return true;
+}
+
+constexpr bool testConstexprMonths(std::chrono::year_month_weekday_last ym)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ym ).month()) != 10) return false;
+ if (static_cast<unsigned>((ym - offset).month()) != 4) return false;
+ return true;
+}
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using years = std::chrono::years;
+ using months = std::chrono::months;
+
+ constexpr month October = std::chrono::October;
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+
+ { // year_month_weekday_last - years
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday_last>() - std::declval<years>());
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<year_month_weekday_last>() - std::declval<years>()));
+
+ static_assert(testConstexprYears(year_month_weekday_last{year{66}, October, weekday_last{Tuesday}}), "");
+
+ year_month_weekday_last ym{year{1234}, October, weekday_last{Tuesday}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_weekday_last ym1 = ym - years{i};
+ assert(ym1.year() == year{1234 - i});
+ assert(ym1.month() == October);
+ assert(ym1.weekday() == Tuesday);
+ assert(ym1.weekday_last() == weekday_last{Tuesday});
+ }
+ }
+
+ { // year_month_weekday_last - months
+
+ ASSERT_NOEXCEPT( std::declval<year_month_weekday_last>() - std::declval<months>());
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<year_month_weekday_last>() - std::declval<months>()));
+
+ static_assert(testConstexprMonths(year_month_weekday_last{year{66}, October, weekday_last{Tuesday}}), "");
+
+ year_month_weekday_last ym{year{1234}, October, weekday_last{Tuesday}};
+ for (unsigned i = 0; i < 10; ++i)
+ {
+ year_month_weekday_last ym1 = ym - months{i};
+ assert(ym1.year() == year{1234});
+ assert(ym1.month() == month{10 - i});
+ assert(ym1.weekday() == Tuesday);
+ assert(ym1.weekday_last() == weekday_last{Tuesday});
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/plus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/plus.pass.cpp
new file mode 100644
index 000000000000..9f8eb9dc0309
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/plus.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last;
+
+// constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
+// Returns: (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last().
+//
+// constexpr year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
+// Returns: ymwdl + dm.
+//
+// constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
+// Returns: {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}.
+//
+// constexpr year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
+// Returns: ymwdl + dy.
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool testConstexprYears(std::chrono::year_month_weekday_last ym)
+{
+ std::chrono::years offset{23};
+ if (static_cast<int>((ym ).year()) != 1) return false;
+ if (static_cast<int>((ym + offset).year()) != 24) return false;
+ if (static_cast<int>((offset + ym).year()) != 24) return false;
+ return true;
+}
+
+constexpr bool testConstexprMonths(std::chrono::year_month_weekday_last ym)
+{
+ std::chrono::months offset{6};
+ if (static_cast<unsigned>((ym ).month()) != 1) return false;
+ if (static_cast<unsigned>((ym + offset).month()) != 7) return false;
+ if (static_cast<unsigned>((offset + ym).month()) != 7) return false;
+ return true;
+}
+
+
+int main()
+{
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using years = std::chrono::years;
+ using months = std::chrono::months;
+
+ constexpr weekday Tuesday = std::chrono::Tuesday;
+ constexpr month January = std::chrono::January;
+
+ { // year_month_weekday_last + months
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last>() + std::declval<months>());
+ ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month_weekday_last>());
+
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<year_month_weekday_last>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<months>() + std::declval<year_month_weekday_last>()));
+
+ static_assert(testConstexprMonths(year_month_weekday_last{year{1}, January, weekday_last{Tuesday}}), "");
+
+ year_month_weekday_last ym{year{1234}, January, weekday_last{Tuesday}};
+ for (int i = 0; i <= 10; ++i) // TODO test wrap-around
+ {
+ year_month_weekday_last ym1 = ym + months{i};
+ year_month_weekday_last ym2 = months{i} + ym;
+ assert(ym1.year() == year(1234));
+ assert(ym2.year() == year(1234));
+ assert(ym1.month() == month(1 + i));
+ assert(ym2.month() == month(1 + i));
+ assert(ym1.weekday() == Tuesday);
+ assert(ym2.weekday() == Tuesday);
+ assert(ym1.weekday_last() == weekday_last{Tuesday});
+ assert(ym2.weekday_last() == weekday_last{Tuesday});
+ assert(ym1 == ym2);
+ }
+ }
+
+ { // year_month_weekday_last + years
+ ASSERT_NOEXCEPT(std::declval<year_month_weekday_last>() + std::declval<years>());
+ ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month_weekday_last>());
+
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<year_month_weekday_last>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month_weekday_last, decltype(std::declval<years>() + std::declval<year_month_weekday_last>()));
+
+ static_assert(testConstexprYears (year_month_weekday_last{year{1}, January, weekday_last{Tuesday}}), "");
+
+ year_month_weekday_last ym{year{1234}, std::chrono::January, weekday_last{Tuesday}};
+ for (int i = 0; i <= 10; ++i)
+ {
+ year_month_weekday_last ym1 = ym + years{i};
+ year_month_weekday_last ym2 = years{i} + ym;
+ assert(ym1.year() == year(1234 + i));
+ assert(ym2.year() == year(1234 + i));
+ assert(ym1.month() == January);
+ assert(ym2.month() == January);
+ assert(ym1.weekday() == Tuesday);
+ assert(ym2.weekday() == Tuesday);
+ assert(ym1.weekday_last() == weekday_last{Tuesday});
+ assert(ym2.weekday_last() == weekday_last{Tuesday});
+ assert(ym1 == ym2);
+ }
+ }
+
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp
new file mode 100644
index 000000000000..46b6ebaed0f3
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+// XFAIL: *
+
+// <chrono>
+// class year_month_weekday_last;
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
+//
+// Returns: os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last().
+
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+ using year = std::chrono::year;
+ using month = std::chrono::month;
+ using weekday = std::chrono::weekday;
+ using weekday_last = std::chrono::weekday_last;
+
+ std::cout << year_month_weekday_last{year{2018}, month{3}, weekday_last{weekday{4}}};
+}
diff --git a/test/std/utilities/time/time.cal/time.cal.ymwdlast/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/types.pass.cpp
new file mode 100644
index 000000000000..a7f3f024ebfe
--- /dev/null
+++ b/test/std/utilities/time/time.cal/time.cal.ymwdlast/types.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+// class year_month_weekday_last_last;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using year_month_weekday_last = std::chrono::year_month_weekday_last;
+
+ static_assert(std::is_trivially_copyable_v<year_month_weekday_last>, "");
+ static_assert(std::is_standard_layout_v<year_month_weekday_last>, "");
+}
diff --git a/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp
new file mode 100644
index 000000000000..0b5757f672a0
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.file/consistency.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+//
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
+
+// <chrono>
+
+// file_clock
+
+// check clock invariants
+
+#include <chrono>
+
+template <class T>
+void test(const T &) {}
+
+int main()
+{
+ typedef std::chrono::file_clock C;
+ static_assert((std::is_same<C::rep, C::duration::rep>::value), "");
+ static_assert((std::is_same<C::period, C::duration::period>::value), "");
+ static_assert((std::is_same<C::duration, C::time_point::duration>::value), "");
+ static_assert((std::is_same<C::time_point::clock, C>::value), "");
+ static_assert(!C::is_steady, "");
+ test(std::chrono::file_clock::is_steady);
+}
diff --git a/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp
new file mode 100644
index 000000000000..955e3ebe9d5b
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.file/file_time.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// file_time
+
+#include <chrono>
+
+#include "test_macros.h"
+
+template <class Dur>
+void test() {
+ ASSERT_SAME_TYPE(std::chrono::file_time<Dur>, std::chrono::time_point<std::chrono::file_clock, Dur>);
+}
+
+int main() {
+ test<std::chrono::nanoseconds>();
+ test<std::chrono::minutes>();
+ test<std::chrono::hours>();
+} \ No newline at end of file
diff --git a/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp
new file mode 100644
index 000000000000..69dfa9180933
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.file/now.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
+
+// <chrono>
+
+// file_clock
+
+// static time_point now() noexcept;
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ typedef std::chrono::file_clock C;
+ ASSERT_NOEXCEPT(C::now());
+
+ C::time_point t1 = C::now();
+ assert(t1.time_since_epoch().count() != 0);
+ assert(C::time_point::min() < t1);
+ assert(C::time_point::max() > t1);
+}
diff --git a/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp b/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp
new file mode 100644
index 000000000000..c0fa0b5bedae
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.file/rep_signed.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// TODO: Remove this when filesystem gets integrated into the dylib
+// REQUIRES: c++filesystem
+
+// <chrono>
+
+// file_clock
+
+// rep should be signed
+
+#include <chrono>
+#include <cassert>
+
+int main()
+{
+ static_assert(std::is_signed<std::chrono::file_clock::rep>::value, "");
+ assert(std::chrono::file_clock::duration::min() <
+ std::chrono::file_clock::duration::zero());
+}
diff --git a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp
index 2f8a707bfa2f..47a610f00317 100644
--- a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp
+++ b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp
@@ -12,9 +12,10 @@
// UNSUPPORTED: asan
// Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!),
-// but before C++17 it requires the symbol to be present in the dylib.
-// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
-// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// but before C++17 it requires the symbol to be present in the dylib, which
+// is only shipped starting with macosx10.9.
+// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
// <chrono>
diff --git a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
index 4458d6f213fa..e5e6de2605f5 100644
--- a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
+++ b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
@@ -14,9 +14,10 @@
// UNSUPPORTED: asan
// Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!),
-// but before C++17 it requires the symbol to be present in the dylib.
-// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
-// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// but before C++17 it requires the symbol to be present in the dylib, which
+// is only shipped starting with macosx10.9.
+// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
// <chrono>
diff --git a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp
index deb4615fa5a1..c5ecb32275e3 100644
--- a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp
+++ b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp
@@ -12,9 +12,10 @@
// UNSUPPORTED: asan
// Starting with C++17, Clock::is_steady is inlined (but not before LLVM-3.9!),
-// but before C++17 it requires the symbol to be present in the dylib.
-// XFAIL: availability=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
-// XFAIL: availability=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// but before C++17 it requires the symbol to be present in the dylib, which
+// is only shipped starting with macosx10.9.
+// XFAIL: with_system_cxx_lib=macosx10.7 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
+// XFAIL: with_system_cxx_lib=macosx10.8 && (c++98 || c++03 || c++11 || c++14 || apple-clang-7 || apple-clang-8.0)
// <chrono>
diff --git a/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp
new file mode 100644
index 000000000000..9f91ca744b73
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.system/local_time.types.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// struct local_t {};
+// template<class Duration>
+// using local_time = time_point<system_clock, Duration>;
+// using local_seconds = sys_time<seconds>;
+// using local_days = sys_time<days>;
+
+// [Example:
+// sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s.
+// sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946’684’800s, which is 10’957 * 86’400s.
+// —end example]
+
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using local_t = std::chrono::local_t;
+ using year = std::chrono::year;
+
+ using seconds = std::chrono::seconds;
+ using minutes = std::chrono::minutes;
+ using days = std::chrono::days;
+
+ using local_seconds = std::chrono::local_seconds;
+ using local_minutes = std::chrono::local_time<minutes>;
+ using local_days = std::chrono::local_days;
+
+ constexpr std::chrono::month January = std::chrono::January;
+
+ ASSERT_SAME_TYPE(std::chrono::local_time<seconds>, local_seconds);
+ ASSERT_SAME_TYPE(std::chrono::local_time<days>, local_days);
+
+// Test the long form, too
+ ASSERT_SAME_TYPE(std::chrono::time_point<local_t, seconds>, local_seconds);
+ ASSERT_SAME_TYPE(std::chrono::time_point<local_t, minutes>, local_minutes);
+ ASSERT_SAME_TYPE(std::chrono::time_point<local_t, days>, local_days);
+
+// Test some well known values
+ local_days d0 = local_days{year{1970}/January/1};
+ local_days d1 = local_days{year{2000}/January/1};
+ ASSERT_SAME_TYPE(decltype(d0.time_since_epoch()), days);
+ assert( d0.time_since_epoch().count() == 0);
+ assert( d1.time_since_epoch().count() == 10957);
+
+ local_seconds s0{d0};
+ local_seconds s1{d1};
+ ASSERT_SAME_TYPE(decltype(s0.time_since_epoch()), seconds);
+ assert( s0.time_since_epoch().count() == 0);
+ assert( s1.time_since_epoch().count() == 946684800L);
+}
diff --git a/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp
new file mode 100644
index 000000000000..299e06818138
--- /dev/null
+++ b/test/std/utilities/time/time.clock/time.clock.system/sys.time.types.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// template<class Duration>
+// using sys_time = time_point<system_clock, Duration>;
+// using sys_seconds = sys_time<seconds>;
+// using sys_days = sys_time<days>;
+
+// [Example:
+// sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s.
+// sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946’684’800s, which is 10’957 * 86’400s.
+// —end example]
+
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using system_clock = std::chrono::system_clock;
+ using year = std::chrono::year;
+
+ using seconds = std::chrono::seconds;
+ using minutes = std::chrono::minutes;
+ using days = std::chrono::days;
+
+ using sys_seconds = std::chrono::sys_seconds;
+ using sys_minutes = std::chrono::sys_time<minutes>;
+ using sys_days = std::chrono::sys_days;
+
+ constexpr std::chrono::month January = std::chrono::January;
+
+ ASSERT_SAME_TYPE(std::chrono::sys_time<seconds>, sys_seconds);
+ ASSERT_SAME_TYPE(std::chrono::sys_time<days>, sys_days);
+
+// Test the long form, too
+ ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, seconds>, sys_seconds);
+ ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, minutes>, sys_minutes);
+ ASSERT_SAME_TYPE(std::chrono::time_point<system_clock, days>, sys_days);
+
+// Test some well known values
+ sys_days d0 = sys_days{year{1970}/January/1};
+ sys_days d1 = sys_days{year{2000}/January/1};
+ ASSERT_SAME_TYPE(decltype(d0.time_since_epoch()), days);
+ assert( d0.time_since_epoch().count() == 0);
+ assert( d1.time_since_epoch().count() == 10957);
+
+ sys_seconds s0{d0};
+ sys_seconds s1{d1};
+ ASSERT_SAME_TYPE(decltype(s0.time_since_epoch()), seconds);
+ assert( s0.time_since_epoch().count() == 0);
+ assert( s1.time_since_epoch().count() == 946684800L);
+}
diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp
index d5c0207c0ee7..e10b35efbb9c 100644
--- a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp
@@ -14,6 +14,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
using namespace std::literals::chrono_literals;
@@ -55,4 +57,5 @@ int main()
assert ( ns == std::chrono::nanoseconds(645));
auto ns2 = 645.ns;
assert ( ns == ns2 );
+
}
diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp
index 5e59e1153787..6e43e3a9a2fa 100644
--- a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp
@@ -7,8 +7,8 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
// UNSUPPORTED: c++98, c++03, c++11
+
#include <chrono>
#include <cassert>
@@ -45,4 +45,27 @@ int main()
assert ( ns == nanoseconds(645));
auto ns2 = 645.ns;
assert ( ns == ns2 );
+
+#if TEST_STD_VER > 17
+ assert(Sunday == weekday(0));
+ assert(Monday == weekday(1));
+ assert(Tuesday == weekday(2));
+ assert(Wednesday == weekday(3));
+ assert(Thursday == weekday(4));
+ assert(Friday == weekday(5));
+ assert(Saturday == weekday(6));
+
+ assert(January == month(1));
+ assert(February == month(2));
+ assert(March == month(3));
+ assert(April == month(4));
+ assert(May == month(5));
+ assert(June == month(6));
+ assert(July == month(7));
+ assert(August == month(8));
+ assert(September == month(9));
+ assert(October == month(10));
+ assert(November == month(11));
+ assert(December == month(12));
+#endif
}
diff --git a/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp b/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp
index 561516b66511..4c4895b2a0bb 100644
--- a/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp
@@ -20,6 +20,7 @@
#include <cassert>
#include "test_macros.h"
+#include "truncate_fp.h"
int main()
{
@@ -41,7 +42,7 @@ int main()
{
std::chrono::duration<int, std::ratio<2, 3> > s1(30);
std::chrono::duration<double, std::ratio<3, 5> > s2(5);
- assert(s1 / s2 == 20./3);
+ assert(s1 / s2 == truncate_fp(20./3));
}
#if TEST_STD_VER >= 11
{
diff --git a/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp b/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp
index 48c3e86e8101..275f87760ad1 100644
--- a/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.special/max.pass.cpp
@@ -11,7 +11,7 @@
// duration
-// static constexpr duration max();
+// static constexpr duration max(); // noexcept after C++17
#include <chrono>
#include <limits>
@@ -23,6 +23,10 @@
template <class D>
void test()
{
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::max());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::max());
+#endif
{
typedef typename D::rep Rep;
Rep max_rep = std::chrono::duration_values<Rep>::max();
diff --git a/test/std/utilities/time/time.duration/time.duration.special/min.pass.cpp b/test/std/utilities/time/time.duration/time.duration.special/min.pass.cpp
index 0d94aaa5869c..daf7165cf903 100644
--- a/test/std/utilities/time/time.duration/time.duration.special/min.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.special/min.pass.cpp
@@ -11,7 +11,7 @@
// duration
-// static constexpr duration min();
+// static constexpr duration min(); // noexcept after C++17
#include <chrono>
#include <limits>
@@ -23,6 +23,10 @@
template <class D>
void test()
{
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::min());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::min());
+#endif
{
typedef typename D::rep Rep;
Rep min_rep = std::chrono::duration_values<Rep>::min();
diff --git a/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp b/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp
index 7b312c5acb50..a43bb099fe60 100644
--- a/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp
+++ b/test/std/utilities/time/time.duration/time.duration.special/zero.pass.cpp
@@ -11,7 +11,7 @@
// duration
-// static constexpr duration zero();
+// static constexpr duration zero(); // noexcept after C++17
#include <chrono>
#include <cassert>
@@ -22,6 +22,10 @@
template <class D>
void test()
{
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<typename D::rep>::zero());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT( std::chrono::duration_values<typename D::rep>::zero());
+#endif
{
typedef typename D::rep Rep;
Rep zero_rep = std::chrono::duration_values<Rep>::zero();
diff --git a/test/std/utilities/time/time.point/time.point.arithmetic/op_+=.pass.cpp b/test/std/utilities/time/time.point/time.point.arithmetic/op_+=.pass.cpp
index ffe855ce9031..d60f6276ae45 100644
--- a/test/std/utilities/time/time.point/time.point.arithmetic/op_+=.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.arithmetic/op_+=.pass.cpp
@@ -12,15 +12,35 @@
// time_point
// time_point& operator+=(const duration& d);
+// constexpr in c++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool constexpr_test()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds Duration;
+ std::chrono::time_point<Clock, Duration> t(Duration(5));
+ t += Duration(4);
+ return t.time_since_epoch() == Duration(9);
+}
+#endif
+
int main()
{
+ {
typedef std::chrono::system_clock Clock;
typedef std::chrono::milliseconds Duration;
std::chrono::time_point<Clock, Duration> t(Duration(3));
t += Duration(2);
assert(t.time_since_epoch() == Duration(5));
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(constexpr_test(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp b/test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp
index acad1cfecb44..9ef952559209 100644
--- a/test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp
@@ -12,15 +12,35 @@
// time_point
// time_point& operator-=(const duration& d);
+// constexpr in c++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER > 14
+constexpr bool constexpr_test()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds Duration;
+ std::chrono::time_point<Clock, Duration> t(Duration(5));
+ t -= Duration(4);
+ return t.time_since_epoch() == Duration(1);
+}
+#endif
+
int main()
{
+ {
typedef std::chrono::system_clock Clock;
typedef std::chrono::milliseconds Duration;
std::chrono::time_point<Clock, Duration> t(Duration(3));
t -= Duration(2);
assert(t.time_since_epoch() == Duration(1));
+ }
+
+#if TEST_STD_VER > 14
+ static_assert(constexpr_test(), "");
+#endif
}
diff --git a/test/std/utilities/time/time.point/time.point.special/max.pass.cpp b/test/std/utilities/time/time.point/time.point.special/max.pass.cpp
index 6bba6fc82787..85447ea414c3 100644
--- a/test/std/utilities/time/time.point/time.point.special/max.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.special/max.pass.cpp
@@ -11,15 +11,21 @@
// time_point
-// static constexpr time_point max();
+// static constexpr time_point max(); // noexcept after C++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
typedef std::chrono::milliseconds Duration;
typedef std::chrono::time_point<Clock, Duration> TP;
+ LIBCPP_ASSERT_NOEXCEPT(TP::max());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT( TP::max());
+#endif
assert(TP::max() == TP(Duration::max()));
}
diff --git a/test/std/utilities/time/time.point/time.point.special/min.pass.cpp b/test/std/utilities/time/time.point/time.point.special/min.pass.cpp
index b1d955c252aa..fab5b4aae22c 100644
--- a/test/std/utilities/time/time.point/time.point.special/min.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.special/min.pass.cpp
@@ -11,15 +11,21 @@
// time_point
-// static constexpr time_point min();
+// static constexpr time_point min(); // noexcept after C++17
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
typedef std::chrono::milliseconds Duration;
typedef std::chrono::time_point<Clock, Duration> TP;
+ LIBCPP_ASSERT_NOEXCEPT(TP::max());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT( TP::max());
+#endif
assert(TP::min() == TP(Duration::min()));
}
diff --git a/test/std/utilities/time/time.traits/time.traits.duration_values/max.pass.cpp b/test/std/utilities/time/time.traits/time.traits.duration_values/max.pass.cpp
index e3754c1f6475..bd4115437947 100644
--- a/test/std/utilities/time/time.traits/time.traits.duration_values/max.pass.cpp
+++ b/test/std/utilities/time/time.traits/time.traits.duration_values/max.pass.cpp
@@ -9,7 +9,7 @@
// <chrono>
-// duration_values::max
+// duration_values::max // noexcept after C++17
#include <chrono>
#include <limits>
@@ -34,4 +34,13 @@ int main()
static_assert(std::chrono::duration_values<Rep>::max() ==
std::numeric_limits<Rep>::max(), "");
#endif
+
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<int>::max());
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<double>::max());
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::max());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::chrono::duration_values<int>::max());
+ ASSERT_NOEXCEPT(std::chrono::duration_values<double>::max());
+ ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::max());
+#endif
}
diff --git a/test/std/utilities/time/time.traits/time.traits.duration_values/min.pass.cpp b/test/std/utilities/time/time.traits/time.traits.duration_values/min.pass.cpp
index 508837375b87..207a9ab5aff6 100644
--- a/test/std/utilities/time/time.traits/time.traits.duration_values/min.pass.cpp
+++ b/test/std/utilities/time/time.traits/time.traits.duration_values/min.pass.cpp
@@ -9,7 +9,7 @@
// <chrono>
-// duration_values::min
+// duration_values::min // noexcept after C++17
#include <chrono>
#include <limits>
@@ -34,4 +34,13 @@ int main()
static_assert(std::chrono::duration_values<Rep>::min() ==
std::numeric_limits<Rep>::lowest(), "");
#endif
+
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<int>::min());
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<double>::min());
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::min());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::chrono::duration_values<int>::min());
+ ASSERT_NOEXCEPT(std::chrono::duration_values<double>::min());
+ ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::min());
+#endif
}
diff --git a/test/std/utilities/time/time.traits/time.traits.duration_values/zero.pass.cpp b/test/std/utilities/time/time.traits/time.traits.duration_values/zero.pass.cpp
index b84a676738a8..614c69b2e386 100644
--- a/test/std/utilities/time/time.traits/time.traits.duration_values/zero.pass.cpp
+++ b/test/std/utilities/time/time.traits/time.traits.duration_values/zero.pass.cpp
@@ -9,7 +9,7 @@
// <chrono>
-// duration_values::zero
+// duration_values::zero // noexcept after C++17
#include <chrono>
#include <cassert>
@@ -25,4 +25,11 @@ int main()
static_assert(std::chrono::duration_values<int>::zero() == 0, "");
static_assert(std::chrono::duration_values<Rep>::zero() == 0, "");
#endif
+
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<int>::zero());
+ LIBCPP_ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::zero());
+#if TEST_STD_VER > 17
+ ASSERT_NOEXCEPT(std::chrono::duration_values<int>::zero());
+ ASSERT_NOEXCEPT(std::chrono::duration_values<Rep>::zero());
+#endif
}
diff --git a/test/std/utilities/time/weeks.pass.cpp b/test/std/utilities/time/weeks.pass.cpp
new file mode 100644
index 000000000000..8e6f283f0ec8
--- /dev/null
+++ b/test/std/utilities/time/weeks.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// using weeks = duration<signed integer type of at least 22 bits, ratio_multiply<ratio<7>, days::period>>;
+
+#include <chrono>
+#include <type_traits>
+#include <limits>
+
+int main()
+{
+ typedef std::chrono::weeks D;
+ typedef D::rep Rep;
+ typedef D::period Period;
+ static_assert(std::is_signed<Rep>::value, "");
+ static_assert(std::is_integral<Rep>::value, "");
+ static_assert(std::numeric_limits<Rep>::digits >= 22, "");
+ static_assert(std::is_same_v<Period, std::ratio_multiply<std::ratio<7>, std::chrono::days::period>>, "");
+}
diff --git a/test/std/utilities/time/years.pass.cpp b/test/std/utilities/time/years.pass.cpp
new file mode 100644
index 000000000000..28a250274249
--- /dev/null
+++ b/test/std/utilities/time/years.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// using years = duration<signed integer type of at least 17 bits, ratio_multiply<ratio<146097, 400>, days::period>>
+
+#include <chrono>
+#include <type_traits>
+#include <limits>
+
+int main()
+{
+ typedef std::chrono::years D;
+ typedef D::rep Rep;
+ typedef D::period Period;
+ static_assert(std::is_signed<Rep>::value, "");
+ static_assert(std::is_integral<Rep>::value, "");
+ static_assert(std::numeric_limits<Rep>::digits >= 17, "");
+ static_assert(std::is_same_v<Period, std::ratio_multiply<std::ratio<146097, 400>, std::chrono::days::period>>, "");
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp
index ce6dcf811e46..977d2b6da54b 100644
--- a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp
@@ -26,8 +26,7 @@ struct X
void operator()() {}
};
-int
-main()
+int main()
{
X x;
std::function<void()> f(x);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
index 210f14be318a..9bc0ef5015f6 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
@@ -15,6 +15,7 @@
// UNSUPPORTED: c++98, c++03
+#include <memory>
#include <tuple>
#include <utility>
#include <cassert>
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
index 457df5602850..bfa7c0d2370c 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
@@ -14,6 +14,7 @@
// See llvm.org/PR20855
+#include <functional>
#include <tuple>
#include <string>
#include <cassert>
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp
index 818001833995..05ff8a4dfd1e 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp
@@ -12,7 +12,7 @@
// template <class... Types> class tuple;
// template <class... Types>
-// class tuple_size<tuple<Types...>>
+// struct tuple_size<tuple<Types...>>
// : public integral_constant<size_t, sizeof...(Types)> { };
// UNSUPPORTED: c++98, c++03
@@ -26,19 +26,19 @@ struct Dummy2 {};
struct Dummy3 {};
template <>
-class std::tuple_size<Dummy1> {
+struct std::tuple_size<Dummy1> {
public:
static size_t value;
};
template <>
-class std::tuple_size<Dummy2> {
+struct std::tuple_size<Dummy2> {
public:
static void value() {}
};
template <>
-class std::tuple_size<Dummy3> {};
+struct std::tuple_size<Dummy3> {};
int main()
{
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp
index ccdd48e4c11d..c4f2e52ab71d 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp
@@ -12,7 +12,7 @@
// template <class... Types> class tuple;
// template <class... Types>
-// class tuple_size<tuple<Types...>>
+// struct tuple_size<tuple<Types...>>
// : public integral_constant<size_t, sizeof...(Types)> { };
// XFAIL: gcc-4.9
@@ -31,7 +31,7 @@ struct Dummy1 {};
struct Dummy2 {};
namespace std {
-template <> class tuple_size<Dummy1> : public integral_constant<size_t, 0> {};
+template <> struct tuple_size<Dummy1> : public integral_constant<size_t, 0> {};
}
template <class T>
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp
index 03fb78caa08e..a18b9fc8976a 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp
@@ -12,7 +12,7 @@
// template <class... Types> class tuple;
// template <class... Types>
-// class tuple_size<tuple<Types...>>
+// struct tuple_size<tuple<Types...>>
// : public integral_constant<size_t, sizeof...(Types)> { };
// UNSUPPORTED: c++98, c++03, c++11, c++14
@@ -129,7 +129,7 @@ void test_before_tuple_size_specialization() {
}
template <>
-class std::tuple_size<Test> {
+struct std::tuple_size<Test> {
public:
static const size_t value = 1;
};
diff --git a/test/std/utilities/type.index/type.index.hash/hash.pass.cpp b/test/std/utilities/type.index/type.index.hash/hash.pass.cpp
index c5ffacfa37e9..14bf08412bb4 100644
--- a/test/std/utilities/type.index/type.index.hash/hash.pass.cpp
+++ b/test/std/utilities/type.index/type.index.hash/hash.pass.cpp
@@ -19,6 +19,7 @@
// };
#include <typeindex>
+#include <type_traits>
#include <cassert>
int main()
diff --git a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
index c738adad7d79..aa86949dd5b3 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
@@ -17,9 +17,10 @@
// pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_args);
-#include <utility>
-#include <tuple>
#include <cassert>
+#include <tuple>
+#include <utility>
+
int main()
{
diff --git a/test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp b/test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp
index 5b0f15ecbb12..4e76e12b9a48 100644
--- a/test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp
+++ b/test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp
@@ -10,12 +10,14 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// <variant>
diff --git a/test/std/utilities/variant/variant.get/get_index.pass.cpp b/test/std/utilities/variant/variant.get/get_index.pass.cpp
index f52dc5556466..dd76fa6c73e0 100644
--- a/test/std/utilities/variant/variant.get/get_index.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.get/get_type.pass.cpp b/test/std/utilities/variant/variant.get/get_type.pass.cpp
index 0a2222cbf277..7b4a6704877f 100644
--- a/test/std/utilities/variant/variant.get/get_type.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_type.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.relops/relops.pass.cpp b/test/std/utilities/variant/variant.relops/relops.pass.cpp
index 4337b4bdbbd7..41a953552150 100644
--- a/test/std/utilities/variant/variant.relops/relops.pass.cpp
+++ b/test/std/utilities/variant/variant.relops/relops.pass.cpp
@@ -85,43 +85,79 @@ template <class Variant> void makeEmpty(Variant &v) {
}
#endif // TEST_HAS_NO_EXCEPTIONS
-void test_equality() {
+struct MyBool {
+ bool value;
+ constexpr explicit MyBool(bool v) : value(v) {}
+ constexpr operator bool() const noexcept { return value; }
+};
+
+struct ComparesToMyBool {
+ int value = 0;
+};
+inline constexpr MyBool operator==(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value == RHS.value);
+}
+inline constexpr MyBool operator!=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value != RHS.value);
+}
+inline constexpr MyBool operator<(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value < RHS.value);
+}
+inline constexpr MyBool operator<=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value <= RHS.value);
+}
+inline constexpr MyBool operator>(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value > RHS.value);
+}
+inline constexpr MyBool operator>=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {
+ return MyBool(LHS.value >= RHS.value);
+}
+
+template <class T1, class T2>
+void test_equality_basic() {
{
- using V = std::variant<int, long>;
- constexpr V v1(42);
- constexpr V v2(42);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{42});
+ constexpr V v2(std::in_place_index<0>, T1{42});
static_assert(v1 == v2, "");
static_assert(v2 == v1, "");
static_assert(!(v1 != v2), "");
static_assert(!(v2 != v1), "");
}
{
- using V = std::variant<int, long>;
- constexpr V v1(42);
- constexpr V v2(43);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{42});
+ constexpr V v2(std::in_place_index<0>, T1{43});
static_assert(!(v1 == v2), "");
static_assert(!(v2 == v1), "");
static_assert(v1 != v2, "");
static_assert(v2 != v1, "");
}
{
- using V = std::variant<int, long>;
- constexpr V v1(42);
- constexpr V v2(42l);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{42});
+ constexpr V v2(std::in_place_index<1>, T2{42});
static_assert(!(v1 == v2), "");
static_assert(!(v2 == v1), "");
static_assert(v1 != v2, "");
static_assert(v2 != v1, "");
}
{
- using V = std::variant<int, long>;
- constexpr V v1(42l);
- constexpr V v2(42l);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<1>, T2{42});
+ constexpr V v2(std::in_place_index<1>, T2{42});
static_assert(v1 == v2, "");
static_assert(v2 == v1, "");
static_assert(!(v1 != v2), "");
static_assert(!(v2 != v1), "");
}
+}
+
+void test_equality() {
+ test_equality_basic<int, long>();
+ test_equality_basic<ComparesToMyBool, int>();
+ test_equality_basic<int, ComparesToMyBool>();
+ test_equality_basic<ComparesToMyBool, ComparesToMyBool>();
#ifndef TEST_HAS_NO_EXCEPTIONS
{
using V = std::variant<int, MakeEmptyT>;
@@ -160,41 +196,54 @@ void test_equality() {
template <class Var>
constexpr bool test_less(const Var &l, const Var &r, bool expect_less,
bool expect_greater) {
+ static_assert(std::is_same_v<decltype(l < r), bool>, "");
+ static_assert(std::is_same_v<decltype(l <= r), bool>, "");
+ static_assert(std::is_same_v<decltype(l > r), bool>, "");
+ static_assert(std::is_same_v<decltype(l >= r), bool>, "");
+
return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&
((l > r) == expect_greater) && (!(l <= r) == expect_greater);
}
-void test_relational() {
+template <class T1, class T2>
+void test_relational_basic() {
{ // same index, same value
- using V = std::variant<int, long>;
- constexpr V v1(1);
- constexpr V v2(1);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{1});
+ constexpr V v2(std::in_place_index<0>, T1{1});
static_assert(test_less(v1, v2, false, false), "");
}
{ // same index, value < other_value
- using V = std::variant<int, long>;
- constexpr V v1(0);
- constexpr V v2(1);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{0});
+ constexpr V v2(std::in_place_index<0>, T1{1});
static_assert(test_less(v1, v2, true, false), "");
}
{ // same index, value > other_value
- using V = std::variant<int, long>;
- constexpr V v1(1);
- constexpr V v2(0);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{1});
+ constexpr V v2(std::in_place_index<0>, T1{0});
static_assert(test_less(v1, v2, false, true), "");
}
{ // LHS.index() < RHS.index()
- using V = std::variant<int, long>;
- constexpr V v1(0);
- constexpr V v2(0l);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<0>, T1{0});
+ constexpr V v2(std::in_place_index<1>, T2{0});
static_assert(test_less(v1, v2, true, false), "");
}
{ // LHS.index() > RHS.index()
- using V = std::variant<int, long>;
- constexpr V v1(0l);
- constexpr V v2(0);
+ using V = std::variant<T1, T2>;
+ constexpr V v1(std::in_place_index<1>, T2{0});
+ constexpr V v2(std::in_place_index<0>, T1{0});
static_assert(test_less(v1, v2, false, true), "");
}
+}
+
+void test_relational() {
+ test_relational_basic<int, long>();
+ test_relational_basic<ComparesToMyBool, int>();
+ test_relational_basic<int, ComparesToMyBool>();
+ test_relational_basic<ComparesToMyBool, ComparesToMyBool>();
#ifndef TEST_HAS_NO_EXCEPTIONS
{ // LHS.index() < RHS.index(), RHS is empty
using V = std::variant<int, MakeEmptyT>;
diff --git a/test/std/utilities/variant/variant.relops/relops_bool_conv.fail.cpp b/test/std/utilities/variant/variant.relops/relops_bool_conv.fail.cpp
new file mode 100644
index 000000000000..ab68bc420470
--- /dev/null
+++ b/test/std/utilities/variant/variant.relops/relops_bool_conv.fail.cpp
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types>
+// constexpr bool
+// operator==(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator<(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator>(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+#include "test_macros.h"
+
+
+struct MyBoolExplicit {
+ bool value;
+ constexpr explicit MyBoolExplicit(bool v) : value(v) {}
+ constexpr explicit operator bool() const noexcept { return value; }
+};
+
+struct ComparesToMyBoolExplicit {
+ int value = 0;
+};
+inline constexpr MyBoolExplicit operator==(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value == RHS.value);
+}
+inline constexpr MyBoolExplicit operator!=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value != RHS.value);
+}
+inline constexpr MyBoolExplicit operator<(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value < RHS.value);
+}
+inline constexpr MyBoolExplicit operator<=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value <= RHS.value);
+}
+inline constexpr MyBoolExplicit operator>(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value > RHS.value);
+}
+inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept {
+ return MyBoolExplicit(LHS.value >= RHS.value);
+}
+
+
+int main() {
+ using V = std::variant<int, ComparesToMyBoolExplicit>;
+ V v1(42);
+ V v2(101);
+ // expected-error-re@variant:* 6 {{static_assert failed {{.*}}"the relational operator does not return a type which is implicitly convertible to bool"}}
+ // expected-error@variant:* 6 {{no viable conversion}}
+ (void)(v1 == v2); // expected-note {{here}}
+ (void)(v1 != v2); // expected-note {{here}}
+ (void)(v1 < v2); // expected-note {{here}}
+ (void)(v1 <= v2); // expected-note {{here}}
+ (void)(v1 > v2); // expected-note {{here}}
+ (void)(v1 >= v2); // expected-note {{here}}
+}
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
index 29228e562d69..6c8a2b86a17e 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
index 068b9a201566..5ea7069f5d11 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
@@ -14,18 +14,19 @@
// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8.0
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
// template <class ...Types> class variant;
-// variant& operator=(variant const&);
+// variant& operator=(variant const&); // constexpr in C++20
#include <cassert>
#include <string>
@@ -239,7 +240,8 @@ void test_copy_assignment_sfinae() {
static_assert(!std::is_copy_assignable<V>::value, "");
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality (see P0602R4).
+#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_copy_assignable<V>::value, "");
@@ -261,6 +263,7 @@ void test_copy_assignment_sfinae() {
using V = std::variant<int, CopyOnly>;
static_assert(std::is_trivially_copy_assignable<V>::value, "");
}
+#endif // > C++17
}
void test_copy_assignment_empty_empty() {
@@ -383,7 +386,8 @@ void test_copy_assignment_same_index() {
}
#endif // TEST_HAS_NO_EXCEPTIONS
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
@@ -440,6 +444,7 @@ void test_copy_assignment_same_index() {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
+#endif // > C++17
}
void test_copy_assignment_different_index() {
@@ -529,7 +534,8 @@ void test_copy_assignment_different_index() {
}
#endif // TEST_HAS_NO_EXCEPTIONS
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
struct {
constexpr Result<long> operator()() const {
@@ -558,10 +564,11 @@ void test_copy_assignment_different_index() {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
+#endif // > C++17
}
template <size_t NewIdx, class ValueType>
-constexpr bool test_constexpr_assign_extension_imp(
+constexpr bool test_constexpr_assign_imp(
std::variant<long, void*, int>&& v, ValueType&& new_value)
{
const std::variant<long, void*, int> cp(
@@ -571,15 +578,17 @@ constexpr bool test_constexpr_assign_extension_imp(
std::get<NewIdx>(v) == std::get<NewIdx>(cp);
}
-void test_constexpr_copy_assignment_extension() {
- // The following tests are for not-yet-standardized behavior (P0602):
+void test_constexpr_copy_assignment() {
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
using V = std::variant<long, void*, int>;
static_assert(std::is_trivially_copyable<V>::value, "");
static_assert(std::is_trivially_copy_assignable<V>::value, "");
- static_assert(test_constexpr_assign_extension_imp<0>(V(42l), 101l), "");
- static_assert(test_constexpr_assign_extension_imp<0>(V(nullptr), 101l), "");
- static_assert(test_constexpr_assign_extension_imp<1>(V(42l), nullptr), "");
- static_assert(test_constexpr_assign_extension_imp<2>(V(42l), 101), "");
+ static_assert(test_constexpr_assign_imp<0>(V(42l), 101l), "");
+ static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), "");
+ static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), "");
+ static_assert(test_constexpr_assign_imp<2>(V(42l), 101), "");
+#endif // > C++17
}
int main() {
@@ -590,5 +599,5 @@ int main() {
test_copy_assignment_different_index();
test_copy_assignment_sfinae();
test_copy_assignment_not_noexcept();
- test_constexpr_copy_assignment_extension();
+ test_constexpr_copy_assignment();
}
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
index c410b4b8f3ef..cee141a8c73a 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
@@ -14,18 +14,20 @@
// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8.0
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// <variant>
// template <class ...Types> class variant;
-// variant& operator=(variant&&) noexcept(see below);
+// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
#include <cassert>
#include <string>
@@ -204,7 +206,8 @@ void test_move_assignment_sfinae() {
static_assert(!std::is_move_assignable<V>::value, "");
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality (see P0602R4).
+#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_move_assignable<V>::value, "");
@@ -230,6 +233,7 @@ void test_move_assignment_sfinae() {
using V = std::variant<int, CopyOnly>;
static_assert(std::is_trivially_move_assignable<V>::value, "");
}
+#endif // > C++17
}
void test_move_assignment_empty_empty() {
@@ -351,7 +355,8 @@ void test_move_assignment_same_index() {
}
#endif // TEST_HAS_NO_EXCEPTIONS
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
@@ -394,6 +399,7 @@ void test_move_assignment_same_index() {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
+#endif // > C++17
}
void test_move_assignment_different_index() {
@@ -443,7 +449,8 @@ void test_move_assignment_different_index() {
}
#endif // TEST_HAS_NO_EXCEPTIONS
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
struct {
constexpr Result<long> operator()() const {
@@ -472,10 +479,11 @@ void test_move_assignment_different_index() {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
+#endif // > C++17
}
template <size_t NewIdx, class ValueType>
-constexpr bool test_constexpr_assign_extension_imp(
+constexpr bool test_constexpr_assign_imp(
std::variant<long, void*, int>&& v, ValueType&& new_value)
{
std::variant<long, void*, int> v2(
@@ -486,15 +494,17 @@ constexpr bool test_constexpr_assign_extension_imp(
std::get<NewIdx>(v) == std::get<NewIdx>(cp);
}
-void test_constexpr_move_assignment_extension() {
- // The following tests are for not-yet-standardized behavior (P0602):
+void test_constexpr_move_assignment() {
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
using V = std::variant<long, void*, int>;
static_assert(std::is_trivially_copyable<V>::value, "");
static_assert(std::is_trivially_move_assignable<V>::value, "");
- static_assert(test_constexpr_assign_extension_imp<0>(V(42l), 101l), "");
- static_assert(test_constexpr_assign_extension_imp<0>(V(nullptr), 101l), "");
- static_assert(test_constexpr_assign_extension_imp<1>(V(42l), nullptr), "");
- static_assert(test_constexpr_assign_extension_imp<2>(V(42l), 101), "");
+ static_assert(test_constexpr_assign_imp<0>(V(42l), 101l), "");
+ static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), "");
+ static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), "");
+ static_assert(test_constexpr_assign_imp<2>(V(42l), 101), "");
+#endif // > C++17
}
int main() {
@@ -505,5 +515,5 @@ int main() {
test_move_assignment_different_index();
test_move_assignment_sfinae();
test_move_assignment_noexcept();
- test_constexpr_move_assignment_extension();
+ test_constexpr_move_assignment();
}
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
index 3f7cd4f0b6d2..d414c3503e78 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -12,6 +12,14 @@
// <variant>
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// template <class ...Types> class variant;
// template <class T> constexpr variant(T&&) noexcept(see below);
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
index 1696f9cc2320..6eeec69c891c 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -10,18 +10,19 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
// template <class ...Types> class variant;
-// variant(variant const&);
+// variant(variant const&); // constexpr in C++20
#include <cassert>
#include <type_traits>
@@ -125,7 +126,8 @@ void test_copy_ctor_sfinae() {
static_assert(!std::is_copy_constructible<V>::value, "");
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality (see P0602R4).
+#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_copy_constructible<V>::value, "");
@@ -143,6 +145,7 @@ void test_copy_ctor_sfinae() {
using V = std::variant<int, TCopyNTMove>;
static_assert(std::is_trivially_copy_constructible<V>::value, "");
}
+#endif // > C++17
}
void test_copy_ctor_basic() {
@@ -173,7 +176,8 @@ void test_copy_ctor_basic() {
assert(std::get<1>(v2).value == 42);
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
constexpr std::variant<int> v(std::in_place_index<0>, 42);
static_assert(v.index() == 0, "");
@@ -216,6 +220,7 @@ void test_copy_ctor_basic() {
static_assert(v2.index() == 1, "");
static_assert(std::get<1>(v2).value == 42, "");
}
+#endif // > C++17
}
void test_copy_ctor_valueless_by_exception() {
@@ -230,17 +235,16 @@ void test_copy_ctor_valueless_by_exception() {
}
template <size_t Idx>
-constexpr bool test_constexpr_copy_ctor_extension_imp(
- std::variant<long, void*, const int> const& v)
-{
+constexpr bool test_constexpr_copy_ctor_imp(std::variant<long, void*, const int> const& v) {
auto v2 = v;
return v2.index() == v.index() &&
v2.index() == Idx &&
std::get<Idx>(v2) == std::get<Idx>(v);
}
-void test_constexpr_copy_ctor_extension() {
- // NOTE: This test is for not yet standardized behavior. (P0602)
+void test_constexpr_copy_ctor() {
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
@@ -251,16 +255,17 @@ void test_constexpr_copy_ctor_extension() {
#else // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_copyable<V>::value, "");
#endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
- static_assert(test_constexpr_copy_ctor_extension_imp<0>(V(42l)), "");
- static_assert(test_constexpr_copy_ctor_extension_imp<1>(V(nullptr)), "");
- static_assert(test_constexpr_copy_ctor_extension_imp<2>(V(101)), "");
+ static_assert(test_constexpr_copy_ctor_imp<0>(V(42l)), "");
+ static_assert(test_constexpr_copy_ctor_imp<1>(V(nullptr)), "");
+ static_assert(test_constexpr_copy_ctor_imp<2>(V(101)), "");
+#endif // > C++17
}
int main() {
test_copy_ctor_basic();
test_copy_ctor_valueless_by_exception();
test_copy_ctor_sfinae();
- test_constexpr_copy_ctor_extension();
+ test_constexpr_copy_ctor();
#if 0
// disable this for the moment; it fails on older compilers.
// Need to figure out which compilers will support it.
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
index 05a09db45bdf..e4278f0e0abc 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
@@ -31,7 +32,7 @@
#include "variant_test_helpers.hpp"
struct NonDefaultConstructible {
- NonDefaultConstructible(int) {}
+ constexpr NonDefaultConstructible(int) {}
};
struct NotNoexcept {
@@ -98,6 +99,11 @@ void test_default_ctor_basic() {
assert(std::get<0>(v) == 0);
}
{
+ std::variant<int, NonDefaultConstructible> v;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 0);
+ }
+ {
using V = std::variant<int, long>;
constexpr V v;
static_assert(v.index() == 0, "");
@@ -109,6 +115,12 @@ void test_default_ctor_basic() {
static_assert(v.index() == 0, "");
static_assert(std::get<0>(v) == 0, "");
}
+ {
+ using V = std::variant<int, NonDefaultConstructible>;
+ constexpr V v;
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 0, "");
+ }
}
int main() {
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
index af6c66213039..0e1ba7bba7dc 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
index 9d0bf55fb538..7dcd2541bbae 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
@@ -12,6 +12,14 @@
// <variant>
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// template <class ...Types> class variant;
// template <size_t I, class Up, class ...Args>
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
index ec2730e8740c..c798efbaaf46 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
index e151572c4666..7d632af9ad04 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
@@ -12,6 +12,14 @@
// <variant>
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
// template <class ...Types> class variant;
// template <class Tp, class Up, class ...Args>
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
index 6b392068d5a9..f59367109671 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -10,18 +10,19 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
// template <class ...Types> class variant;
-// variant(variant&&) noexcept(see below);
+// variant(variant&&) noexcept(see below); // constexpr in C++20
#include <cassert>
#include <string>
@@ -146,7 +147,8 @@ void test_move_ctor_sfinae() {
static_assert(!std::is_move_constructible<V>::value, "");
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality (see P0602R4).
+#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_move_constructible<V>::value, "");
@@ -164,6 +166,7 @@ void test_move_ctor_sfinae() {
using V = std::variant<int, TMoveNTCopy>;
static_assert(std::is_trivially_move_constructible<V>::value, "");
}
+#endif // > C++17
}
template <typename T>
@@ -213,7 +216,8 @@ void test_move_ctor_basic() {
assert(std::get<1>(v2).value == 42);
}
- // The following tests are for not-yet-standardized behavior (P0602):
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
@@ -286,6 +290,7 @@ void test_move_ctor_basic() {
static_assert(result.index == 1, "");
static_assert(result.value.value == 42, "");
}
+#endif // > C++17
}
void test_move_ctor_valueless_by_exception() {
@@ -299,9 +304,7 @@ void test_move_ctor_valueless_by_exception() {
}
template <size_t Idx>
-constexpr bool test_constexpr_ctor_extension_imp(
- std::variant<long, void*, const int> const& v)
-{
+constexpr bool test_constexpr_ctor_imp(std::variant<long, void*, const int> const& v) {
auto copy = v;
auto v2 = std::move(copy);
return v2.index() == v.index() &&
@@ -309,8 +312,9 @@ constexpr bool test_constexpr_ctor_extension_imp(
std::get<Idx>(v2) == std::get<Idx>(v);
}
-void test_constexpr_move_ctor_extension() {
- // NOTE: This test is for not yet standardized behavior. (P0602)
+void test_constexpr_move_ctor() {
+ // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
+#if TEST_STD_VER > 17
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
@@ -322,9 +326,10 @@ void test_constexpr_move_ctor_extension() {
static_assert(std::is_trivially_copyable<V>::value, "");
#endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_move_constructible<V>::value, "");
- static_assert(test_constexpr_ctor_extension_imp<0>(V(42l)), "");
- static_assert(test_constexpr_ctor_extension_imp<1>(V(nullptr)), "");
- static_assert(test_constexpr_ctor_extension_imp<2>(V(101)), "");
+ static_assert(test_constexpr_ctor_imp<0>(V(42l)), "");
+ static_assert(test_constexpr_ctor_imp<1>(V(nullptr)), "");
+ static_assert(test_constexpr_ctor_imp<2>(V(101)), "");
+#endif // > C++17
}
int main() {
@@ -332,5 +337,5 @@ int main() {
test_move_ctor_valueless_by_exception();
test_move_noexcept();
test_move_ctor_sfinae();
- test_constexpr_move_ctor_extension();
+ test_constexpr_move_ctor();
}
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
index 20848db0fc70..d281927c7423 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
index 28a0c582853b..939e8f39dc05 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
index 923ffd33a75c..4fed14167515 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
index c01d333441a9..f03e95644e54 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
index 8025b9e0774e..6d78de3a48ba 100644
--- a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
@@ -10,14 +10,6 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// The following compilers don't consider a type an aggregate type (and
-// consequently not a literal type) if it has a base class at all.
-// In C++17, an aggregate type is allowed to have a base class if it's not
-// virtual, private, nor protected (e.g. ConstexprTestTypes:::NoCtors).
-// XFAIL: gcc-5, gcc-6
-// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
-// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8.0
-
// <variant>
// template <class ...Types> class variant;
@@ -33,14 +25,20 @@
#include "test_macros.h"
#include "variant_test_helpers.hpp"
+
int main() {
{
- using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ using V = std::variant<int, long>;
constexpr V v;
static_assert(v.index() == 0, "");
}
{
using V = std::variant<int, long>;
+ V v;
+ assert(v.index() == 0);
+ }
+ {
+ using V = std::variant<int, long>;
constexpr V v(std::in_place_index<1>);
static_assert(v.index() == 1, "");
}
diff --git a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
index 660a21c4f31d..9ccdc2221994 100644
--- a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
@@ -10,14 +10,6 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// The following compilers don't consider a type an aggregate type (and
-// consequently not a literal type) if it has a base class at all.
-// In C++17, an aggregate type is allowed to have a base class if it's not
-// virtual, private, nor protected (e.g. ConstexprTestTypes:::NoCtors).
-// XFAIL: gcc-5, gcc-6
-// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8
-// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8.0
-
// <variant>
// template <class ...Types> class variant;
@@ -33,13 +25,19 @@
#include "test_macros.h"
#include "variant_test_helpers.hpp"
+
int main() {
{
- using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ using V = std::variant<int, long>;
constexpr V v;
static_assert(!v.valueless_by_exception(), "");
}
{
+ using V = std::variant<int, long>;
+ V v;
+ assert(!v.valueless_by_exception());
+ }
+ {
using V = std::variant<int, long, std::string>;
const V v("abc");
assert(!v.valueless_by_exception());
diff --git a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
index b81b3ff6a967..ec85ce7679b4 100644
--- a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
diff --git a/test/std/utilities/variant/variant.visit/visit.pass.cpp b/test/std/utilities/variant/variant.visit/visit.pass.cpp
index c0db967933b0..693369abb2d5 100644
--- a/test/std/utilities/variant/variant.visit/visit.pass.cpp
+++ b/test/std/utilities/variant/variant.visit/visit.pass.cpp
@@ -10,12 +10,13 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: with_system_cxx_lib=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
-// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: availability=macosx10.13
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
// <variant>
// template <class Visitor, class... Variants>
diff --git a/test/support/any_helpers.h b/test/support/any_helpers.h
index afc85c97ff46..ec8654d1903c 100644
--- a/test/support/any_helpers.h
+++ b/test/support/any_helpers.h
@@ -68,6 +68,7 @@ template <class> constexpr bool has_value_member(long) { return false; }
// Assert that an 'any' object stores the specified 'Type' and 'value'.
template <class Type>
std::enable_if_t<has_value_member<Type>(0)>
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
assertContains(std::any const& a, int value) {
assert(a.has_value());
assert(containsType<Type>(a));
@@ -76,6 +77,7 @@ assertContains(std::any const& a, int value) {
template <class Type, class Value>
std::enable_if_t<!has_value_member<Type>(0)>
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
assertContains(std::any const& a, Value value) {
assert(a.has_value());
assert(containsType<Type>(a));
@@ -86,6 +88,7 @@ assertContains(std::any const& a, Value value) {
// Modify the value of a "test type" stored within an any to the specified
// 'value'.
template <class Type>
+_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
void modifyValue(std::any& a, int value) {
using namespace std;
using namespace std::experimental;
diff --git a/test/support/archetypes.hpp b/test/support/archetypes.hpp
index 533f5869b5ab..a0ea7c3ce8e1 100644
--- a/test/support/archetypes.hpp
+++ b/test/support/archetypes.hpp
@@ -225,7 +225,6 @@ namespace ExplicitTypes {
#include "archetypes.ipp"
}
-
//============================================================================//
//
namespace NonConstexprTypes {
@@ -242,11 +241,17 @@ namespace NonLiteralTypes {
}
//============================================================================//
+// Non-throwing implicit test types
+namespace NonThrowingTypes {
+#define DEFINE_NOEXCEPT noexcept
+#include "archetypes.ipp"
+}
+
+//============================================================================//
// Non-Trivially Copyable Implicit Test Types
namespace NonTrivialTypes {
#define DEFINE_CTOR {}
#define DEFINE_ASSIGN { return *this; }
-#define DEFINE_DEFAULT_CTOR = default
#include "archetypes.ipp"
}
@@ -314,7 +319,7 @@ constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
return L.value != R.value;
}
-} // end namespace ValueTypes
+} // end namespace ConstexprTestTypes
//============================================================================//
@@ -337,7 +342,7 @@ constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
return L.value != R.value;
}
-} // end namespace ValueTypes
+} // end namespace ExplicitConstexprTestTypes
//============================================================================//
@@ -359,7 +364,7 @@ constexpr bool operator!=(Tp const& L, Tp const& R) noexcept {
return L.value != R.value;
}
-} // end namespace TrivialValueTypes
+} // end namespace TrivialTestTypes
//============================================================================//
//
diff --git a/test/support/archetypes.ipp b/test/support/archetypes.ipp
index 36045017907f..943dcf9f5d8a 100644
--- a/test/support/archetypes.ipp
+++ b/test/support/archetypes.ipp
@@ -5,6 +5,9 @@
#ifndef DEFINE_EXPLICIT
#define DEFINE_EXPLICIT
#endif
+#ifndef DEFINE_NOEXCEPT
+#define DEFINE_NOEXCEPT
+#endif
#ifndef DEFINE_CONSTEXPR
#ifdef TEST_WORKAROUND_EDG_EXPLICIT_CONSTEXPR
#define DEFINE_CONSTEXPR
@@ -36,114 +39,114 @@ struct AllCtors : DEFINE_BASE(AllCtors) {
using Base = DEFINE_BASE(AllCtors);
using Base::Base;
using Base::operator=;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_CTOR;
- DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_ASSIGN;
- DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_CTOR;
+ DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
+ DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors &&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
DEFINE_DTOR(AllCtors)
};
struct NoCtors : DEFINE_BASE(NoCtors) {
using Base = DEFINE_BASE(NoCtors);
- DEFINE_EXPLICIT NoCtors() = delete;
- DEFINE_EXPLICIT NoCtors(NoCtors const&) = delete;
- NoCtors& operator=(NoCtors const&) = delete;
+ DEFINE_EXPLICIT NoCtors() DEFINE_NOEXCEPT = delete;
+ DEFINE_EXPLICIT NoCtors(NoCtors const&) DEFINE_NOEXCEPT = delete;
+ NoCtors& operator=(NoCtors const&) DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(NoCtors)
};
struct NoDefault : DEFINE_BASE(NoDefault) {
using Base = DEFINE_BASE(NoDefault);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() = delete;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR NoDefault() DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(NoDefault)
};
struct DefaultOnly : DEFINE_BASE(DefaultOnly) {
using Base = DEFINE_BASE(DefaultOnly);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_DEFAULT_CTOR;
- DefaultOnly(DefaultOnly const&) = delete;
- DefaultOnly& operator=(DefaultOnly const&) = delete;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete;
+ DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(DefaultOnly)
};
struct Copyable : DEFINE_BASE(Copyable) {
using Base = DEFINE_BASE(Copyable);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_CTOR;
- Copyable &operator=(Copyable const &) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_CTOR;
+ Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN;
DEFINE_DTOR(Copyable)
};
struct CopyOnly : DEFINE_BASE(CopyOnly) {
using Base = DEFINE_BASE(CopyOnly);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) = delete;
- CopyOnly &operator=(CopyOnly const &) DEFINE_ASSIGN;
- CopyOnly &operator=(CopyOnly &&) = delete;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete;
+ CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN;
+ CopyOnly &operator=(CopyOnly &&) DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(CopyOnly)
};
struct NonCopyable : DEFINE_BASE(NonCopyable) {
using Base = DEFINE_BASE(NonCopyable);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) = delete;
- NonCopyable &operator=(NonCopyable const &) = delete;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete;
+ NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(NonCopyable)
};
struct MoveOnly : DEFINE_BASE(MoveOnly) {
using Base = DEFINE_BASE(MoveOnly);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_CTOR;
- MoveOnly &operator=(MoveOnly &&) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_CTOR;
+ MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
DEFINE_DTOR(MoveOnly)
};
struct CopyAssignable : DEFINE_BASE(CopyAssignable) {
using Base = DEFINE_BASE(CopyAssignable);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() = delete;
- CopyAssignable& operator=(CopyAssignable const&) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignable() DEFINE_NOEXCEPT = delete;
+ CopyAssignable& operator=(CopyAssignable const&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
DEFINE_DTOR(CopyAssignable)
};
struct CopyAssignOnly : DEFINE_BASE(CopyAssignOnly) {
using Base = DEFINE_BASE(CopyAssignOnly);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() = delete;
- CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_ASSIGN;
- CopyAssignOnly& operator=(CopyAssignOnly &&) = delete;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyAssignOnly() DEFINE_NOEXCEPT = delete;
+ CopyAssignOnly& operator=(CopyAssignOnly const&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
+ CopyAssignOnly& operator=(CopyAssignOnly &&) DEFINE_NOEXCEPT = delete;
DEFINE_DTOR(CopyAssignOnly)
};
struct MoveAssignOnly : DEFINE_BASE(MoveAssignOnly) {
using Base = DEFINE_BASE(MoveAssignOnly);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() = delete;
- MoveAssignOnly& operator=(MoveAssignOnly const&) = delete;
- MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveAssignOnly() DEFINE_NOEXCEPT = delete;
+ MoveAssignOnly& operator=(MoveAssignOnly const&) DEFINE_NOEXCEPT = delete;
+ MoveAssignOnly& operator=(MoveAssignOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
DEFINE_DTOR(MoveAssignOnly)
};
struct ConvertingType : DEFINE_BASE(ConvertingType) {
using Base = DEFINE_BASE(ConvertingType);
using Base::Base;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_DEFAULT_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_CTOR;
- DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_CTOR;
- ConvertingType& operator=(ConvertingType const&) DEFINE_ASSIGN;
- ConvertingType& operator=(ConvertingType &&) DEFINE_ASSIGN;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_CTOR;
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_CTOR;
+ ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
+ ConvertingType& operator=(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_ASSIGN;
template <class ...Args>
- DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) {}
+ DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(Args&&...) DEFINE_NOEXCEPT {}
template <class Arg>
- ConvertingType& operator=(Arg&&) { return *this; }
+ ConvertingType& operator=(Arg&&) DEFINE_NOEXCEPT { return *this; }
DEFINE_DTOR(ConvertingType)
};
@@ -165,6 +168,7 @@ using ApplyTypes = List<
#undef DEFINE_BASE
#undef DEFINE_EXPLICIT
+#undef DEFINE_NOEXCEPT
#undef DEFINE_CONSTEXPR
#undef DEFINE_ASSIGN_CONSTEXPR
#undef DEFINE_CTOR
diff --git a/test/support/counting_predicates.hpp b/test/support/counting_predicates.hpp
index 050b51b75bb1..a0b3ca518ecc 100644
--- a/test/support/counting_predicates.hpp
+++ b/test/support/counting_predicates.hpp
@@ -7,9 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef __COUNTING_PREDICATES_H
-#define __COUNTING_PREDICATES_H
+#ifndef TEST_SUPPORT_COUNTING_PREDICATES_H
+#define TEST_SUPPORT_COUNTING_PREDICATES_H
+#include <cstddef>
template <typename Predicate, typename Arg>
struct unary_counting_predicate {
@@ -27,7 +28,7 @@ public:
private:
Predicate p_;
mutable size_t count_;
- };
+};
template <typename Predicate, typename Arg1, typename Arg2=Arg1>
@@ -47,6 +48,6 @@ public:
private:
Predicate p_;
mutable size_t count_;
- };
+};
-#endif // __COUNTING_PREDICATES_H
+#endif // TEST_SUPPORT_COUNTING_PREDICATES_H
diff --git a/test/support/filesystem_dynamic_test_helper.py b/test/support/filesystem_dynamic_test_helper.py
index 081e678b6e84..078958274978 100644
--- a/test/support/filesystem_dynamic_test_helper.py
+++ b/test/support/filesystem_dynamic_test_helper.py
@@ -1,10 +1,12 @@
import sys
import os
+import socket
import stat
# Ensure that this is being run on a specific platform
assert sys.platform.startswith('linux') or sys.platform.startswith('darwin') \
- or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd')
+ or sys.platform.startswith('cygwin') or sys.platform.startswith('freebsd') \
+ or sys.platform.startswith('netbsd')
def env_path():
ep = os.environ.get('LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT')
@@ -75,8 +77,13 @@ def create_fifo(source):
def create_socket(source):
- mode = 0o600 | stat.S_IFSOCK
- os.mknod(sanitize(source), mode)
+ sock = socket.socket(socket.AF_UNIX)
+ sanitized_source = sanitize(source)
+ # AF_UNIX sockets may have very limited path length, so split it
+ # into chdir call (with technically unlimited length) followed
+ # by bind() relative to the directory
+ os.chdir(os.path.dirname(sanitized_source))
+ sock.bind(os.path.basename(sanitized_source))
if __name__ == '__main__':
diff --git a/test/support/filesystem_test_helper.hpp b/test/support/filesystem_test_helper.hpp
index f027928700b9..467abd5fc672 100644
--- a/test/support/filesystem_test_helper.hpp
+++ b/test/support/filesystem_test_helper.hpp
@@ -2,6 +2,9 @@
#define FILESYSTEM_TEST_HELPER_HPP
#include "filesystem_include.hpp"
+
+#include <unistd.h> // for ftruncate
+
#include <cassert>
#include <cstdio> // for printf
#include <string>
@@ -147,13 +150,46 @@ struct scoped_test_env
return raw;
}
- std::string create_file(std::string filename, std::size_t size = 0) {
+ // Purposefully using a size potentially larger than off_t here so we can
+ // test the behavior of libc++fs when it is built with _FILE_OFFSET_BITS=64
+ // but the caller is not (std::filesystem also uses uintmax_t rather than
+ // off_t). On a 32-bit system this allows us to create a file larger than
+ // 2GB.
+ std::string create_file(std::string filename, uintmax_t size = 0) {
+#if defined(__LP64__)
+ auto large_file_fopen = fopen;
+ auto large_file_ftruncate = ftruncate;
+ using large_file_offset_t = off_t;
+#else
+ auto large_file_fopen = fopen64;
+ auto large_file_ftruncate = ftruncate64;
+ using large_file_offset_t = off64_t;
+#endif
+
filename = sanitize_path(std::move(filename));
- std::string out_str(size, 'a');
- {
- std::ofstream out(filename.c_str());
- out << out_str;
+
+ if (size > std::numeric_limits<large_file_offset_t>::max()) {
+ fprintf(stderr, "create_file(%s, %ju) too large\n",
+ filename.c_str(), size);
+ abort();
}
+
+ FILE* file = large_file_fopen(filename.c_str(), "we");
+ if (file == nullptr) {
+ fprintf(stderr, "fopen %s failed: %s\n", filename.c_str(),
+ strerror(errno));
+ abort();
+ }
+
+ if (large_file_ftruncate(
+ fileno(file), static_cast<large_file_offset_t>(size)) == -1) {
+ fprintf(stderr, "ftruncate %s %ju failed: %s\n", filename.c_str(),
+ size, strerror(errno));
+ fclose(file);
+ abort();
+ }
+
+ fclose(file);
return filename;
}
diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h
index a3af9e1db66d..454749397441 100644
--- a/test/support/min_allocator.h
+++ b/test/support/min_allocator.h
@@ -14,6 +14,7 @@
#include <cstdlib>
#include <cstddef>
#include <cassert>
+#include <climits>
#include "test_macros.h"
@@ -131,6 +132,59 @@ public:
friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);}
};
+template <class T>
+struct cpp03_allocator : bare_allocator<T>
+{
+ typedef T value_type;
+ typedef value_type* pointer;
+
+ static bool construct_called;
+
+ // Returned value is not used but it's not prohibited.
+ pointer construct(pointer p, const value_type& val)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ return p;
+ }
+
+ std::size_t max_size() const
+ {
+ return UINT_MAX / sizeof(T);
+ }
+};
+template <class T> bool cpp03_allocator<T>::construct_called = false;
+
+template <class T>
+struct cpp03_overload_allocator : bare_allocator<T>
+{
+ typedef T value_type;
+ typedef value_type* pointer;
+
+ static bool construct_called;
+
+ void construct(pointer p, const value_type& val)
+ {
+ construct(p, val, std::is_class<T>());
+ }
+ void construct(pointer p, const value_type& val, std::true_type)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ }
+ void construct(pointer p, const value_type& val, std::false_type)
+ {
+ ::new(p) value_type(val);
+ construct_called = true;
+ }
+
+ std::size_t max_size() const
+ {
+ return UINT_MAX / sizeof(T);
+ }
+};
+template <class T> bool cpp03_overload_allocator<T>::construct_called = false;
+
#if TEST_STD_VER >= 11
diff --git a/test/support/nasty_macros.hpp b/test/support/nasty_macros.hpp
index 76d8ab0e720f..3c2a5e27a96e 100644
--- a/test/support/nasty_macros.hpp
+++ b/test/support/nasty_macros.hpp
@@ -22,7 +22,11 @@
#define _J NASTY_MACRO
#define _K NASTY_MACRO
#define _L NASTY_MACRO
+// Because FreeBSD uses _M in its <sys/types.h>, and it is hard to avoid
+// including that header, only define _M for other operating systems.
+#ifndef __FreeBSD__
#define _M NASTY_MACRO
+#endif
#define _N NASTY_MACRO
#define _O NASTY_MACRO
#define _P NASTY_MACRO
@@ -45,6 +49,9 @@
#define _CRPC NASTY_MACRO
#define _CPC NASTY_MACRO
+// yvals.h on MINGW defines this macro
+#define _C2 NASTY_MACRO
+
// Test that libc++ doesn't use names reserved by WIN32 API Macros.
// NOTE: Obviously we can only define these on non-windows platforms.
#ifndef _WIN32
diff --git a/test/support/poisoned_hash_helper.hpp b/test/support/poisoned_hash_helper.hpp
index 6f42ebf8b480..07cb7269215e 100644
--- a/test/support/poisoned_hash_helper.hpp
+++ b/test/support/poisoned_hash_helper.hpp
@@ -147,7 +147,6 @@ void test_hash_enabled(InputKey const& key) {
#endif
// Hashable requirements
- using CKey = ConvertibleTo<Key>;
static_assert(can_hash<Hash(Key&)>(), "");
static_assert(can_hash<Hash(Key const&)>(), "");
static_assert(can_hash<Hash(Key&&)>(), "");
@@ -187,7 +186,6 @@ void test_hash_disabled() {
>::value, "");
// Hashable requirements
- using CKey = ConvertibleTo<Key>;
static_assert(!can_hash<Hash(Key&)>(), "");
static_assert(!can_hash<Hash(Key const&)>(), "");
static_assert(!can_hash<Hash(Key&&)>(), "");
diff --git a/test/support/test_comparisons.h b/test/support/test_comparisons.h
index a3f8dd9f8c35..cf094eb65b82 100644
--- a/test/support/test_comparisons.h
+++ b/test/support/test_comparisons.h
@@ -23,8 +23,8 @@
#include "test_macros.h"
// Test all six comparison operations for sanity
-template <class T>
-TEST_CONSTEXPR_CXX14 bool testComparisons6(const T& t1, const T& t2, bool isEqual, bool isLess)
+template <class T, class U = T>
+TEST_CONSTEXPR_CXX14 bool testComparisons6(const T& t1, const U& t2, bool isEqual, bool isLess)
{
if (isEqual)
{
@@ -81,47 +81,47 @@ TEST_CONSTEXPR_CXX14 bool testComparisons6Values(Param val1, Param val2)
{
const bool isEqual = val1 == val2;
const bool isLess = val1 < val2;
-
- return testComparisons6(T{val1}, T{val2}, isEqual, isLess);
+
+ return testComparisons6(T(val1), T(val2), isEqual, isLess);
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons6AreNoexcept()
{
- ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() < std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() <= std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() > std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() >= std::declval<const T&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() < std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() <= std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() > std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() >= std::declval<const U&>());
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons6ReturnBool()
{
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() < std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() <= std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() > std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() >= std::declval<const T&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() < std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() <= std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() > std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() >= std::declval<const U&>()), bool);
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons6ConvertibleToBool()
{
- static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() < std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() <= std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() > std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() >= std::declval<const T&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() < std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() <= std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() > std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() >= std::declval<const U&>()), bool>::value), "");
}
-// Test all six comparison operations for sanity
-template <class T>
-TEST_CONSTEXPR_CXX14 bool testComparisons2(const T& t1, const T& t2, bool isEqual)
+// Test all two comparison operations for sanity
+template <class T, class U = T>
+TEST_CONSTEXPR_CXX14 bool testComparisons2(const T& t1, const U& t2, bool isEqual)
{
if (isEqual)
{
@@ -130,7 +130,7 @@ TEST_CONSTEXPR_CXX14 bool testComparisons2(const T& t1, const T& t2, bool isEqua
if ( (t1 != t2)) return false;
if ( (t2 != t1)) return false;
}
- else /* greater */
+ else /* not equal */
{
if ( (t1 == t2)) return false;
if ( (t2 == t1)) return false;
@@ -146,30 +146,30 @@ template <class T, class Param>
TEST_CONSTEXPR_CXX14 bool testComparisons2Values(Param val1, Param val2)
{
const bool isEqual = val1 == val2;
-
- return testComparisons2(T{val1}, T{val2}, isEqual);
+
+ return testComparisons2(T(val1), T(val2), isEqual);
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons2AreNoexcept()
{
- ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const T&>());
- ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const T&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() == std::declval<const U&>());
+ ASSERT_NOEXCEPT(std::declval<const T&>() != std::declval<const U&>());
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons2ReturnBool()
{
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const T&>()), bool);
- ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const T&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() == std::declval<const U&>()), bool);
+ ASSERT_SAME_TYPE(decltype(std::declval<const T&>() != std::declval<const U&>()), bool);
}
-template <class T>
+template <class T, class U = T>
void AssertComparisons2ConvertibleToBool()
{
- static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const T&>()), bool>::value), "");
- static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const T&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() == std::declval<const U&>()), bool>::value), "");
+ static_assert((std::is_convertible<decltype(std::declval<const T&>() != std::declval<const U&>()), bool>::value), "");
}
#endif // TEST_COMPARISONS_H
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
index ac6ec79b9235..e45253534174 100644
--- a/test/support/test_macros.h
+++ b/test/support/test_macros.h
@@ -11,7 +11,18 @@
#ifndef SUPPORT_TEST_MACROS_HPP
#define SUPPORT_TEST_MACROS_HPP
-#include <ciso646> // Get STL specific macros like _LIBCPP_VERSION
+// Attempt to get STL specific macros like _LIBCPP_VERSION using the most
+// minimal header possible. If we're testing libc++, we should use `<__config>`.
+// If <__config> isn't available, fall back to <ciso646>.
+#ifdef __has_include
+# if __has_include("<__config>")
+# include <__config>
+# define TEST_IMP_INCLUDED_HEADER
+# endif
+#endif
+#ifndef TEST_IMP_INCLUDED_HEADER
+#include <ciso646>
+#endif
#if defined(__GNUC__)
#pragma GCC diagnostic push
@@ -69,6 +80,7 @@
#define TEST_CLANG_VER (__clang_major__ * 100) + __clang_minor__
#elif defined(__GNUC__)
#define TEST_GCC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
+#define TEST_GCC_VER_NEW (TEST_GCC_VER * 10 + __GNUC_PATCHLEVEL__)
#endif
/* Make a nice name for the standard version */
@@ -87,12 +99,15 @@
#endif
#endif
-// Attempt to deduce GCC version
-#if defined(_LIBCPP_VERSION) && __has_include(<features.h>)
+// Attempt to deduce the GLIBC version
+#if (defined(__has_include) && __has_include(<features.h>)) || \
+ defined(__linux__)
#include <features.h>
+#if defined(__GLIBC_PREREQ)
#define TEST_HAS_GLIBC
#define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor)
#endif
+#endif
#if TEST_STD_VER >= 11
#define TEST_ALIGNOF(...) alignof(__VA_ARGS__)
@@ -112,7 +127,11 @@
# define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
# endif
#else
-#define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
+#if defined(TEST_COMPILER_CLANG)
+# define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__)
+#else
+# define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
+#endif
#define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__)))
#define TEST_CONSTEXPR
#define TEST_CONSTEXPR_CXX14
@@ -124,22 +143,33 @@
// Sniff out to see if the underling C library has C11 features
// Note that at this time (July 2018), MacOS X and iOS do NOT.
-#if __ISO_C_VISIBLE >= 2011
+// This is cribbed from __config; but lives here as well because we can't assume libc++
+#if __ISO_C_VISIBLE >= 2011 || TEST_STD_VER >= 11
# if defined(__FreeBSD__)
+// Specifically, FreeBSD does NOT have timespec_get, even though they have all
+// the rest of C11 - this is PR#38495
# define TEST_HAS_C11_FEATURES
# elif defined(__Fuchsia__)
# define TEST_HAS_C11_FEATURES
+# define TEST_HAS_TIMESPEC_GET
# elif defined(__linux__)
-# if !defined(_LIBCPP_HAS_MUSL_LIBC)
-# if _LIBCPP_GLIBC_PREREQ(2, 17)
+// This block preserves the old behavior used by include/__config:
+// _LIBCPP_GLIBC_PREREQ would be defined to 0 if __GLIBC_PREREQ was not
+// available. The configuration here may be too vague though, as Bionic, uClibc,
+// newlib, etc may all support these features but need to be configured.
+# if defined(TEST_GLIBC_PREREQ)
+# if TEST_GLIBC_PREREQ(2, 17)
+# define TEST_HAS_TIMESPEC_GET
# define TEST_HAS_C11_FEATURES
# endif
-# else // defined(_LIBCPP_HAS_MUSL_LIBC)
+# elif defined(_LIBCPP_HAS_MUSL_LIBC)
# define TEST_HAS_C11_FEATURES
+# define TEST_HAS_TIMESPEC_GET
# endif
# elif defined(_WIN32)
# if defined(_MSC_VER) && !defined(__MINGW32__)
# define TEST_HAS_C11_FEATURES // Using Microsoft's C Runtime library
+# define TEST_HAS_TIMESPEC_GET
# endif
# endif
#endif
@@ -196,8 +226,9 @@
// FIXME: Fix this feature check when either (A) a compiler provides a complete
// implementation, or (b) a feature check macro is specified
+#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER < 1920 || _MSVC_LANG <= 201703L
#define TEST_HAS_NO_SPACESHIP_OPERATOR
-
+#endif
#if TEST_STD_VER < 11
#define ASSERT_NOEXCEPT(...)
@@ -274,6 +305,16 @@ inline void DoNotOptimize(Tp const& value) {
}
#endif
+#if defined(__GNUC__)
+#define TEST_ALWAYS_INLINE __attribute__((always_inline))
+#define TEST_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+#define TEST_ALWAYS_INLINE __forceinline
+#define TEST_NOINLINE __declspec(noinline)
+#else
+#define TEST_ALWAYS_INLINE
+#define TEST_NOINLINE
+#endif
#if defined(__GNUC__)
#pragma GCC diagnostic pop
diff --git a/test/support/truncate_fp.h b/test/support/truncate_fp.h
new file mode 100644
index 000000000000..83b2b2cffebd
--- /dev/null
+++ b/test/support/truncate_fp.h
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+inline long double truncate_fp(long double val) {
+ volatile long double sink = val;
+ return sink;
+}
+
+inline double truncate_fp(double val) {
+ volatile double sink = val;
+ return sink;
+}
+
+inline float truncate_fp(float val) {
+ volatile float sink = val;
+ return sink;
+}
diff --git a/test/support/unique_ptr_test_helper.h b/test/support/unique_ptr_test_helper.h
index 6fb9eaa24679..18c8f780be40 100644
--- a/test/support/unique_ptr_test_helper.h
+++ b/test/support/unique_ptr_test_helper.h
@@ -98,7 +98,6 @@ public:
template <class IncompleteT = IncompleteType,
class Del = std::default_delete<IncompleteT>, class... Args>
void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
- using ValueT = typename std::remove_all_extents<IncompleteT>::type;
checkNumIncompleteTypeAlive(expect_alive);
{
StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
diff --git a/utils/ci/macos-backdeployment.sh b/utils/ci/macos-backdeployment.sh
new file mode 100755
index 000000000000..1f01fa397c9a
--- /dev/null
+++ b/utils/ci/macos-backdeployment.sh
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+
+set -ue
+
+function usage() {
+ cat <<EOM
+$(basename ${0}) [-h|--help] --libcxx-root <LIBCXX-ROOT> --libcxxabi-root <LIBCXXABI-ROOT> --std <STD> --arch <ARCHITECTURE> --deployment-target <TARGET> --sdk-version <SDK-VERSION> [--lit-args <ARGS...>]
+
+This script is used to continually test the back-deployment use case of libc++ and libc++abi on MacOS.
+
+ --libcxx-root Full path to the root of the libc++ repository to test.
+ --libcxxabi-root Full path to the root of the libc++abi repository to test.
+ --std Version of the C++ Standard to run the tests under (c++03, c++11, etc..).
+ --arch Architecture to build the tests for (32, 64).
+ --deployment-target The deployment target to run the tests for. This should be a version number of MacOS (e.g. 10.12). All MacOS versions until and including 10.7 are supported.
+ --sdk-version The version of the SDK to test with. This should be a version number of MacOS (e.g. 10.12). We'll link against the libc++ dylib in that SDK, but we'll run against the one on the given deployment target.
+ [--lit-args] Additional arguments to pass to lit (optional). If there are multiple arguments, quote them to pass them as a single argument to this script.
+ [--no-cleanup] Do not cleanup the temporary directory that was used for testing at the end. This can be useful to debug failures. Make sure to clean up manually after.
+ [-h, --help] Print this help.
+EOM
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --libcxx-root)
+ LIBCXX_ROOT="${2}"
+ if [[ ! -d "${LIBCXX_ROOT}" ]]; then
+ echo "--libcxx-root '${LIBCXX_ROOT}' is not a valid directory"
+ usage
+ exit 1
+ fi
+ shift; shift
+ ;;
+ --libcxxabi-root)
+ LIBCXXABI_ROOT="${2}"
+ if [[ ! -d "${LIBCXXABI_ROOT}" ]]; then
+ echo "--libcxxabi-root '${LIBCXXABI_ROOT}' is not a valid directory"
+ usage
+ exit 1
+ fi
+ shift; shift
+ ;;
+ --std)
+ STD="${2}"
+ shift; shift
+ ;;
+ --arch)
+ ARCH="${2}"
+ shift; shift
+ ;;
+ --deployment-target)
+ DEPLOYMENT_TARGET="${2}"
+ shift; shift
+ ;;
+ --sdk-version)
+ MACOS_SDK_VERSION="${2}"
+ shift; shift
+ ;;
+ --lit-args)
+ ADDITIONAL_LIT_ARGS="${2}"
+ shift; shift
+ ;;
+ --no-cleanup)
+ NO_CLEANUP=""
+ shift
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "${1} is not a supported argument"
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+if [[ -z ${LIBCXX_ROOT+x} ]]; then echo "--libcxx-root is a required parameter"; usage; exit 1; fi
+if [[ -z ${LIBCXXABI_ROOT+x} ]]; then echo "--libcxxabi-root is a required parameter"; usage; exit 1; fi
+if [[ -z ${STD+x} ]]; then echo "--std is a required parameter"; usage; exit 1; fi
+if [[ -z ${ARCH+x} ]]; then echo "--arch is a required parameter"; usage; exit 1; fi
+if [[ -z ${DEPLOYMENT_TARGET+x} ]]; then echo "--deployment-target is a required parameter"; usage; exit 1; fi
+if [[ -z ${MACOS_SDK_VERSION+x} ]]; then echo "--sdk-version is a required parameter"; usage; exit 1; fi
+if [[ -z ${ADDITIONAL_LIT_ARGS+x} ]]; then ADDITIONAL_LIT_ARGS=""; fi
+
+
+TEMP_DIR="$(mktemp -d)"
+echo "Created temporary directory ${TEMP_DIR}"
+function cleanup {
+ if [[ -z ${NO_CLEANUP+x} ]]; then
+ echo "Removing temporary directory ${TEMP_DIR}"
+ rm -rf "${TEMP_DIR}"
+ else
+ echo "Temporary directory is at '${TEMP_DIR}', make sure to clean it up yourself"
+ fi
+}
+trap cleanup EXIT
+
+
+LLVM_ROOT="${TEMP_DIR}/llvm"
+LIBCXX_BUILD_DIR="${TEMP_DIR}/libcxx-build"
+LIBCXX_INSTALL_DIR="${TEMP_DIR}/libcxx-install"
+LIBCXXABI_BUILD_DIR="${TEMP_DIR}/libcxxabi-build"
+LIBCXXABI_INSTALL_DIR="${TEMP_DIR}/libcxxabi-install"
+
+PREVIOUS_DYLIBS_URL="http://lab.llvm.org:8080/roots/libcxx-roots.tar.gz"
+LLVM_TARBALL_URL="https://github.com/llvm-mirror/llvm/archive/master.tar.gz"
+export CC="$(xcrun --find clang)"
+export CXX="$(xcrun --find clang++)"
+
+
+echo "@@@ Downloading LLVM tarball of master (only used for CMake configuration) @@@"
+mkdir "${LLVM_ROOT}"
+curl -L "${LLVM_TARBALL_URL}" | tar -xz --strip-components=1 -C "${LLVM_ROOT}"
+echo "@@@@@@"
+
+
+echo "@@@ Configuring architecture-related stuff @@@"
+if [[ "${ARCH}" == "64" ]]; then CMAKE_ARCH_STRING="x86_64"; else CMAKE_ARCH_STRING="i386"; fi
+if [[ "${ARCH}" == "64" ]]; then LIT_ARCH_STRING=""; else LIT_ARCH_STRING="--param=enable_32bit=true"; fi
+echo "@@@@@@"
+
+
+echo "@@@ Configuring CMake for libc++ @@@"
+mkdir -p "${LIBCXX_BUILD_DIR}"
+(cd "${LIBCXX_BUILD_DIR}" &&
+ xcrun cmake "${LIBCXX_ROOT}" -GNinja \
+ -DLLVM_PATH="${LLVM_ROOT}" \
+ -DCMAKE_INSTALL_PREFIX="${LIBCXX_INSTALL_DIR}" \
+ -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCH_STRING}"
+)
+echo "@@@@@@"
+
+
+echo "@@@ Configuring CMake for libc++abi @@@"
+mkdir -p "${LIBCXXABI_BUILD_DIR}"
+(cd "${LIBCXXABI_BUILD_DIR}" &&
+ xcrun cmake "${LIBCXXABI_ROOT}" -GNinja \
+ -DLIBCXXABI_LIBCXX_PATH="${LIBCXX_ROOT}" \
+ -DLLVM_PATH="${LLVM_ROOT}" \
+ -DCMAKE_INSTALL_PREFIX="${LIBCXXABI_INSTALL_DIR}" \
+ -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCH_STRING}"
+)
+echo "@@@@@@"
+
+
+echo "@@@ Installing the latest libc++ headers @@@"
+ninja -C "${LIBCXX_BUILD_DIR}" install-cxx-headers
+echo "@@@@@@"
+
+
+echo "@@@ Downloading dylibs for older deployment targets @@@"
+# TODO: The tarball should contain libc++abi.dylib too, we shouldn't be relying on the system's
+# TODO: We should also link against the libc++abi.dylib that was shipped in the SDK
+PREVIOUS_DYLIBS_DIR="${TEMP_DIR}/libcxx-dylibs"
+mkdir "${PREVIOUS_DYLIBS_DIR}"
+curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${PREVIOUS_DYLIBS_DIR}"
+LIBCXX_ON_DEPLOYMENT_TARGET="${PREVIOUS_DYLIBS_DIR}/macOS/${DEPLOYMENT_TARGET}/libc++.dylib"
+LIBCXXABI_ON_DEPLOYMENT_TARGET="/usr/lib/libc++abi.dylib"
+LIBCXX_IN_SDK="${PREVIOUS_DYLIBS_DIR}/macOS/${MACOS_SDK_VERSION}/libc++.dylib"
+echo "@@@@@@"
+
+
+# TODO: We need to also run the tests for libc++abi.
+# TODO: Make sure lit will actually run against the libc++abi we specified
+echo "@@@ Running tests for libc++ @@@"
+"${LIBCXX_BUILD_DIR}/bin/llvm-lit" -sv "${LIBCXX_ROOT}/test" \
+ --param=enable_experimental=false \
+ --param=enable_filesystem=false \
+ ${LIT_ARCH_STRING} \
+ --param=cxx_under_test="${CXX}" \
+ --param=cxx_headers="${LIBCXX_INSTALL_DIR}/include/c++/v1" \
+ --param=std="${STD}" \
+ --param=platform="macosx${DEPLOYMENT_TARGET}" \
+ --param=cxx_runtime_root="$(dirname "${LIBCXX_ON_DEPLOYMENT_TARGET}")" \
+ --param=abi_library_path="$(dirname "${LIBCXXABI_ON_DEPLOYMENT_TARGET}")" \
+ --param=use_system_cxx_lib="$(dirname "${LIBCXX_IN_SDK}")" \
+ ${ADDITIONAL_LIT_ARGS}
+echo "@@@@@@"
diff --git a/utils/ci/macos-trunk.sh b/utils/ci/macos-trunk.sh
new file mode 100755
index 000000000000..b365cc6d8e36
--- /dev/null
+++ b/utils/ci/macos-trunk.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+set -ue
+
+function usage() {
+ cat <<EOM
+$(basename ${0}) [-h|--help] --libcxx-root <LIBCXX-ROOT> --libcxxabi-root <LIBCXXABI-ROOT> --std <STD> --arch <ARCHITECTURE> [--lit-args <ARGS...>]
+
+This script is used to continually test libc++ and libc++abi trunk on MacOS.
+
+ --libcxx-root Full path to the root of the libc++ repository to test.
+ --libcxxabi-root Full path to the root of the libc++abi repository to test.
+ --std Version of the C++ Standard to run the tests under (c++03, c++11, etc..).
+ --arch Architecture to build the tests for (32, 64).
+ [--lit-args] Additional arguments to pass to lit (optional). If there are multiple arguments, quote them to pass them as a single argument to this script.
+ [--no-cleanup] Do not cleanup the temporary directory that was used for testing at the end. This can be useful to debug failures. Make sure to clean up manually after.
+ [-h, --help] Print this help.
+EOM
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --libcxx-root)
+ LIBCXX_ROOT="${2}"
+ if [[ ! -e "${LIBCXX_ROOT}" ]]; then
+ echo "--libcxx-root '${LIBCXX_ROOT}' is not a valid directory"
+ usage
+ exit 1
+ fi
+ shift; shift
+ ;;
+ --libcxxabi-root)
+ LIBCXXABI_ROOT="${2}"
+ if [[ ! -e "${LIBCXXABI_ROOT}" ]]; then
+ echo "--libcxxabi-root '${LIBCXXABI_ROOT}' is not a valid directory"
+ usage
+ exit 1
+ fi
+ shift; shift
+ ;;
+ --std)
+ STD="${2}"
+ shift; shift
+ ;;
+ --arch)
+ ARCH="${2}"
+ shift; shift
+ ;;
+ --lit-args)
+ ADDITIONAL_LIT_ARGS="${2}"
+ shift; shift
+ ;;
+ --no-cleanup)
+ NO_CLEANUP=""
+ shift
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "${1} is not a supported argument"
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+if [[ -z ${LIBCXX_ROOT+x} ]]; then echo "--libcxx-root is a required parameter"; usage; exit 1; fi
+if [[ -z ${LIBCXXABI_ROOT+x} ]]; then echo "--libcxxabi-root is a required parameter"; usage; exit 1; fi
+if [[ -z ${STD+x} ]]; then echo "--std is a required parameter"; usage; exit 1; fi
+if [[ -z ${ARCH+x} ]]; then echo "--arch is a required parameter"; usage; exit 1; fi
+if [[ -z ${ADDITIONAL_LIT_ARGS+x} ]]; then ADDITIONAL_LIT_ARGS=""; fi
+
+
+TEMP_DIR="$(mktemp -d)"
+echo "Created temporary directory ${TEMP_DIR}"
+function cleanup {
+ if [[ -z ${NO_CLEANUP+x} ]]; then
+ echo "Removing temporary directory ${TEMP_DIR}"
+ rm -rf "${TEMP_DIR}"
+ else
+ echo "Temporary directory is at '${TEMP_DIR}', make sure to clean it up yourself"
+ fi
+}
+trap cleanup EXIT
+
+
+LLVM_ROOT="${TEMP_DIR}/llvm"
+LIBCXX_BUILD_DIR="${TEMP_DIR}/libcxx-build"
+LIBCXX_INSTALL_DIR="${TEMP_DIR}/libcxx-install"
+LIBCXXABI_BUILD_DIR="${TEMP_DIR}/libcxxabi-build"
+LIBCXXABI_INSTALL_DIR="${TEMP_DIR}/libcxxabi-install"
+
+LLVM_TARBALL_URL="https://github.com/llvm-mirror/llvm/archive/master.tar.gz"
+export CC="$(xcrun --find clang)"
+export CXX="$(xcrun --find clang++)"
+
+
+echo "@@@ Downloading LLVM tarball of master (only used for CMake configuration) @@@"
+mkdir "${LLVM_ROOT}"
+curl -L "${LLVM_TARBALL_URL}" | tar -xz --strip-components=1 -C "${LLVM_ROOT}"
+echo "@@@@@@"
+
+
+echo "@@@ Setting up LIT flags @@@"
+LIT_FLAGS="-sv --param=std=${STD} ${ADDITIONAL_LIT_ARGS}"
+if [[ "${ARCH}" == "32" ]]; then
+ LIT_FLAGS+=" --param=enable_32bit=true"
+fi
+echo "@@@@@@"
+
+
+echo "@@@ Configuring CMake for libc++ @@@"
+mkdir -p "${LIBCXX_BUILD_DIR}"
+(cd "${LIBCXX_BUILD_DIR}" &&
+ xcrun cmake "${LIBCXX_ROOT}" -GNinja \
+ -DLLVM_PATH="${LLVM_ROOT}" \
+ -DCMAKE_INSTALL_PREFIX="${LIBCXX_INSTALL_DIR}" \
+ -DLLVM_LIT_ARGS="${LIT_FLAGS}" \
+ -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" # Build a universal dylib
+)
+echo "@@@@@@"
+
+
+echo "@@@ Configuring CMake for libc++abi @@@"
+mkdir -p "${LIBCXXABI_BUILD_DIR}"
+(cd "${LIBCXXABI_BUILD_DIR}" &&
+ xcrun cmake "${LIBCXXABI_ROOT}" -GNinja \
+ -DLIBCXXABI_LIBCXX_PATH="${LIBCXX_ROOT}" \
+ -DLLVM_PATH="${LLVM_ROOT}" \
+ -DCMAKE_INSTALL_PREFIX="${LIBCXXABI_INSTALL_DIR}" \
+ -DLLVM_LIT_ARGS="${LIT_FLAGS}" \
+ -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" # Build a universal dylib
+)
+echo "@@@@@@"
+
+
+echo "@@@ Building libc++.dylib and libc++abi.dylib from sources (just to make sure it works) @@@"
+ninja -C "${LIBCXX_BUILD_DIR}" install-cxx
+ninja -C "${LIBCXXABI_BUILD_DIR}" install-cxxabi
+echo "@@@@@@"
+
+
+echo "@@@ Running tests for libc++ @@@"
+# TODO: We should run check-cxx-abilist too
+ninja -C "${LIBCXX_BUILD_DIR}" check-cxx
+echo "@@@@@@"
+
+
+echo "@@@ Running tests for libc++abi @@@"
+ninja -C "${LIBCXXABI_BUILD_DIR}" check-cxxabi
+echo "@@@@@@"
diff --git a/utils/docker/build_docker_image.sh b/utils/docker/build_docker_image.sh
new file mode 100755
index 000000000000..0d2d6d313c7b
--- /dev/null
+++ b/utils/docker/build_docker_image.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+#===- libcxx/utils/docker/build_docker_image.sh ----------------------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===//
+set -e
+
+IMAGE_SOURCE=""
+DOCKER_REPOSITORY=""
+DOCKER_TAG=""
+
+function show_usage() {
+ cat << EOF
+Usage: build_docker_image.sh [options] [-- [cmake_args]...]
+
+Available options:
+ General:
+ -h|--help show this help message
+ Docker-specific:
+ -s|--source image source dir (i.e. debian8, nvidia-cuda, etc)
+ -d|--docker-repository docker repository for the image
+ -t|--docker-tag docker tag for the image
+
+Required options: --source and --docker-repository.
+
+For example, running:
+$ build_docker_image.sh -s debian9 -d mydocker/debian9-clang -t latest
+will produce two docker images:
+ mydocker/debian9-clang-build:latest - an intermediate image used to compile
+ clang.
+ mydocker/clang-debian9:latest - a small image with preinstalled clang.
+Please note that this example produces a not very useful installation, since it
+doesn't override CMake defaults, which produces a Debug and non-boostrapped
+version of clang.
+EOF
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ -s|--source)
+ shift
+ IMAGE_SOURCE="$1"
+ shift
+ ;;
+ -d|--docker-repository)
+ shift
+ DOCKER_REPOSITORY="$1"
+ shift
+ ;;
+ -t|--docker-tag)
+ shift
+ DOCKER_TAG="$1"
+ shift
+ ;;
+ *)
+ echo "Unknown argument $1"
+ exit 1
+ ;;
+ esac
+done
+
+
+command -v docker >/dev/null ||
+ {
+ echo "Docker binary cannot be found. Please install Docker to use this script."
+ exit 1
+ }
+
+if [ "$IMAGE_SOURCE" == "" ]; then
+ echo "Required argument missing: --source"
+ exit 1
+fi
+
+if [ "$DOCKER_REPOSITORY" == "" ]; then
+ echo "Required argument missing: --docker-repository"
+ exit 1
+fi
+
+SOURCE_DIR=$(dirname $0)
+if [ ! -d "$SOURCE_DIR/$IMAGE_SOURCE" ]; then
+ echo "No sources for '$IMAGE_SOURCE' were found in $SOURCE_DIR"
+ exit 1
+fi
+
+BUILD_DIR=$(mktemp -d)
+trap "rm -rf $BUILD_DIR" EXIT
+echo "Using a temporary directory for the build: $BUILD_DIR"
+
+cp -r "$SOURCE_DIR/$IMAGE_SOURCE" "$BUILD_DIR/$IMAGE_SOURCE"
+cp -r "$SOURCE_DIR/scripts" "$BUILD_DIR/scripts"
+
+
+if [ "$DOCKER_TAG" != "" ]; then
+ DOCKER_TAG=":$DOCKER_TAG"
+fi
+
+echo "Building ${DOCKER_REPOSITORY}${DOCKER_TAG} from $IMAGE_SOURCE"
+docker build -t "${DOCKER_REPOSITORY}${DOCKER_TAG}" \
+ -f "$BUILD_DIR/$IMAGE_SOURCE/Dockerfile" \
+ "$BUILD_DIR"
+echo "Done"
diff --git a/utils/docker/debian9/Dockerfile b/utils/docker/debian9/Dockerfile
new file mode 100644
index 000000000000..8dc43f40105b
--- /dev/null
+++ b/utils/docker/debian9/Dockerfile
@@ -0,0 +1,115 @@
+#===- libcxx/utils/docker/debian9/Dockerfile -------------------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===----------------------------------------------------------------------===//
+
+# Setup the base builder image with the packages we'll need to build GCC and Clang from source.
+FROM launcher.gcr.io/google/debian9:latest as builder-base
+LABEL maintainer "libc++ Developers"
+
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ ca-certificates \
+ gnupg \
+ build-essential \
+ wget \
+ subversion \
+ unzip \
+ automake \
+ python \
+ cmake \
+ ninja-build \
+ curl \
+ git \
+ gcc-multilib \
+ g++-multilib \
+ libc6-dev \
+ bison \
+ flex \
+ libtool \
+ autoconf \
+ binutils-dev \
+ binutils-gold \
+ software-properties-common && \
+ update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.gold" 20 && \
+ update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.bfd" 10
+
+# Build GCC 4.9 for testing our C++11 against
+FROM builder-base as gcc-49-builder
+LABEL maintainer "libc++ Developers"
+
+ADD scripts/build_gcc.sh /tmp/build_gcc.sh
+
+RUN git clone --depth=1 --branch gcc-4_9_4-release git://gcc.gnu.org/git/gcc.git /tmp/gcc-4.9.4
+RUN cd /tmp/gcc-4.9.4/ && ./contrib/download_prerequisites
+RUN /tmp/build_gcc.sh --source /tmp/gcc-4.9.4 --to /opt/gcc-4.9.4
+
+# Build GCC ToT for testing in all dialects.
+FROM builder-base as gcc-tot-builder
+LABEL maintainer "libc++ Developers"
+
+ADD scripts/build_gcc.sh /tmp/build_gcc.sh
+
+RUN git clone --depth=1 git://gcc.gnu.org/git/gcc.git /tmp/gcc-tot
+RUN cd /tmp/gcc-tot && ./contrib/download_prerequisites
+RUN /tmp/build_gcc.sh --source /tmp/gcc-tot --to /opt/gcc-tot
+
+# Build LLVM 4.0 which is used to test against a "legacy" compiler.
+FROM builder-base as llvm-4-builder
+LABEL maintainer "libc++ Developers"
+
+ADD scripts/checkout_git.sh /tmp/checkout_git.sh
+ADD scripts/build_install_llvm.sh /tmp/build_install_llvm.sh
+
+RUN /tmp/checkout_git.sh --to /tmp/llvm-4.0 -p clang -p compiler-rt --branch release_40
+RUN /tmp/build_install_llvm.sh \
+ --install /opt/llvm-4.0 \
+ --source /tmp/llvm-4.0 \
+ --build /tmp/build-llvm-4.0 \
+ -i install-clang -i install-clang-headers \
+ -i install-compiler-rt \
+ -- \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ -DLLVM_ENABLE_ASSERTIONS=ON
+
+# Stage 2. Produce a minimal release image with build results.
+FROM launcher.gcr.io/google/debian9:latest
+LABEL maintainer "libc++ Developers"
+
+# Copy over the GCC and Clang installations
+COPY --from=gcc-49-builder /opt/gcc-4.9.4 /opt/gcc-4.9.4
+COPY --from=gcc-tot-builder /opt/gcc-tot /opt/gcc-tot
+COPY --from=llvm-4-builder /opt/llvm-4.0 /opt/llvm-4.0
+
+RUN ln -s /opt/gcc-4.9.4/bin/gcc /usr/local/bin/gcc-4.9 && \
+ ln -s /opt/gcc-4.9.4/bin/g++ /usr/local/bin/g++-4.9
+
+RUN apt-get update && \
+ apt-get install -y \
+ ca-certificates \
+ gnupg \
+ build-essential \
+ apt-transport-https \
+ curl \
+ software-properties-common
+
+RUN apt-get install -y --no-install-recommends \
+ systemd \
+ sysvinit-utils \
+ cmake \
+ subversion \
+ git \
+ ninja-build \
+ gcc-multilib \
+ g++-multilib \
+ python \
+ buildbot-slave
+
+ADD scripts/install_clang_packages.sh /tmp/install_clang_packages.sh
+RUN /tmp/install_clang_packages.sh && rm /tmp/install_clang_packages.sh
+
+RUN git clone https://git.llvm.org/git/libcxx.git /libcxx
diff --git a/utils/docker/scripts/build_gcc.sh b/utils/docker/scripts/build_gcc.sh
new file mode 100755
index 000000000000..85feb16acd6a
--- /dev/null
+++ b/utils/docker/scripts/build_gcc.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+#===- libcxx/utils/docker/scripts/build-gcc.sh ----------------------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===-----------------------------------------------------------------------===//
+
+set -e
+
+
+function show_usage() {
+ cat << EOF
+Usage: build-gcc.sh [options]
+
+Run autoconf with the specified arguments. Used inside docker container.
+
+Available options:
+ -h|--help show this help message
+ --source the source path from which to run the configuration.
+ --to destination directory where to install the targets.
+Required options: --to, at least one --install-target.
+
+All options after '--' are passed to CMake invocation.
+EOF
+}
+
+GCC_INSTALL_DIR=""
+GCC_SOURCE_DIR=""
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --to)
+ shift
+ GCC_INSTALL_DIR="$1"
+ shift
+ ;;
+ --source)
+ shift
+ GCC_SOURCE_DIR="$1"
+ shift
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown option: $1"
+ exit 1
+ esac
+done
+
+if [ "$GCC_INSTALL_DIR" == "" ]; then
+ echo "No install directory. Please specify the --to argument."
+ exit 1
+fi
+
+if [ "$GCC_SOURCE_DIR" == "" ]; then
+ echo "No source directory. Please specify the --source argument."
+ exit 1
+fi
+
+GCC_NAME=`basename $GCC_SOURCE_DIR`
+GCC_BUILD_DIR="/tmp/gcc-build-root/build-$GCC_NAME"
+
+mkdir -p "$GCC_INSTALL_DIR"
+mkdir -p "$GCC_BUILD_DIR"
+pushd "$GCC_BUILD_DIR"
+
+# Run the build as specified in the build arguments.
+echo "Running configuration"
+$GCC_SOURCE_DIR/configure --prefix=$GCC_INSTALL_DIR \
+ --disable-bootstrap --disable-libgomp --disable-libitm \
+ --disable-libvtv --disable-libcilkrts --disable-libmpx \
+ --disable-liboffloadmic --disable-libcc1 --enable-languages=c,c++
+
+NPROC=`nproc`
+echo "Running build with $NPROC threads"
+make -j$NPROC
+
+echo "Installing to $GCC_INSTALL_DIR"
+make install -j$NPROC
+
+popd
+
+# Cleanup.
+rm -rf "$GCC_BUILD_DIR"
+
+echo "Done" \ No newline at end of file
diff --git a/utils/docker/scripts/build_install_llvm.sh b/utils/docker/scripts/build_install_llvm.sh
new file mode 100755
index 000000000000..6f19a96a1b7d
--- /dev/null
+++ b/utils/docker/scripts/build_install_llvm.sh
@@ -0,0 +1,114 @@
+#!/usr/bin/env bash
+#===- llvm/utils/docker/scripts/build_install_llvm.sh ---------------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===-----------------------------------------------------------------------===//
+
+set -e
+
+function show_usage() {
+ cat << EOF
+Usage: build_install_llvm.sh [options] -- [cmake-args]
+
+Run cmake with the specified arguments. Used inside docker container.
+Passes additional -DCMAKE_INSTALL_PREFIX and puts the build results into
+the directory specified by --to option.
+
+Available options:
+ -h|--help show this help message
+ -i|--install-target name of a cmake install target to build and include in
+ the resulting archive. Can be specified multiple times.
+ --install destination directory where to install the targets.
+ --source location of the source tree.
+ --build location to use as the build directory.
+Required options: --to, --source, --build, and at least one --install-target.
+
+All options after '--' are passed to CMake invocation.
+EOF
+}
+
+CMAKE_ARGS=""
+CMAKE_INSTALL_TARGETS=""
+CLANG_INSTALL_DIR=""
+CLANG_SOURCE_DIR=""
+CLANG_BUILD_DIR=""
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -i|--install-target)
+ shift
+ CMAKE_INSTALL_TARGETS="$CMAKE_INSTALL_TARGETS $1"
+ shift
+ ;;
+ --source)
+ shift
+ CLANG_SOURCE_DIR="$1"
+ shift
+ ;;
+ --build)
+ shift
+ CLANG_BUILD_DIR="$1"
+ shift
+ ;;
+ --install)
+ shift
+ CLANG_INSTALL_DIR="$1"
+ shift
+ ;;
+ --)
+ shift
+ CMAKE_ARGS="$*"
+ shift $#
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown option: $1"
+ exit 1
+ esac
+done
+
+if [ "$CLANG_SOURCE_DIR" == "" ]; then
+ echo "No source directory. Please pass --source."
+ exit 1
+fi
+
+if [ "$CLANG_BUILD_DIR" == "" ]; then
+ echo "No build directory. Please pass --build"
+ exit 1
+fi
+
+if [ "$CMAKE_INSTALL_TARGETS" == "" ]; then
+ echo "No install targets. Please pass one or more --install-target."
+ exit 1
+fi
+
+if [ "$CLANG_INSTALL_DIR" == "" ]; then
+ echo "No install directory. Please specify the --to argument."
+ exit 1
+fi
+
+echo "Building in $CLANG_BUILD_DIR"
+mkdir -p "$CLANG_BUILD_DIR"
+pushd "$CLANG_BUILD_DIR"
+
+# Run the build as specified in the build arguments.
+echo "Running build"
+cmake -GNinja \
+ -DCMAKE_INSTALL_PREFIX="$CLANG_INSTALL_DIR" \
+ $CMAKE_ARGS \
+ "$CLANG_SOURCE_DIR"
+ninja $CMAKE_INSTALL_TARGETS
+
+popd
+
+# Cleanup.
+rm -rf "$CLANG_BUILD_DIR"
+
+echo "Done"
diff --git a/utils/docker/scripts/checkout_git.sh b/utils/docker/scripts/checkout_git.sh
new file mode 100755
index 000000000000..222700229c5b
--- /dev/null
+++ b/utils/docker/scripts/checkout_git.sh
@@ -0,0 +1,130 @@
+#!/usr/bin/env bash
+#===- llvm/utils/docker/scripts/checkout.sh ---------------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===-----------------------------------------------------------------------===//
+
+set -e
+
+function show_usage() {
+ cat << EOF
+Usage: checkout.sh [options]
+
+Checkout svn sources into /tmp/clang-build/src. Used inside a docker container.
+
+Available options:
+ -h|--help show this help message
+ -b|--branch svn branch to checkout, i.e. 'trunk',
+ 'branches/release_40'
+ (default: 'trunk')
+ -p|--llvm-project name of an svn project to checkout.
+ For clang, please use 'clang', not 'cfe'.
+ Project 'llvm' is always included and ignored, if
+ specified.
+ Can be specified multiple times.
+EOF
+}
+
+LLVM_BRANCH=""
+# We always checkout llvm
+LLVM_PROJECTS="llvm"
+SOURCE_DIR=""
+
+function contains_project() {
+ local TARGET_PROJ="$1"
+ local PROJ
+ for PROJ in $LLVM_PROJECTS; do
+ if [ "$PROJ" == "$TARGET_PROJ" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --to)
+ shift
+ SOURCE_DIR="$1"
+ shift
+ ;;
+ -b|--branch)
+ shift
+ LLVM_BRANCH="$1"
+ shift
+ ;;
+ -p|--llvm-project)
+ shift
+ PROJ="$1"
+ shift
+
+ if [ "$PROJ" == "cfe" ]; then
+ PROJ="clang"
+ fi
+
+ if ! contains_project "$PROJ" ; then
+ if [ "$PROJ" == "clang-tools-extra" ] && [ ! contains_project "clang" ]; then
+ echo "Project 'clang-tools-extra' specified before 'clang'. Adding 'clang' to a list of projects first."
+ LLVM_PROJECTS="$LLVM_PROJECTS clang"
+ fi
+ LLVM_PROJECTS="$LLVM_PROJECTS $PROJ"
+ else
+ echo "Project '$PROJ' is already enabled, ignoring extra occurrences."
+ fi
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown option: $1"
+ exit 1
+ esac
+done
+
+if [ "$SOURCE_DIR" == "" ]; then
+ echo "Must specify checkout directory using --to"
+ exit 1
+fi
+
+if [ "$LLVM_BRANCH" == "" ]; then
+ GIT_BRANCH_ARG=""
+else
+ GIT_BRANCH_ARG="--branch $LLVM_BRANCH"
+fi
+
+if [ "$LLVM_SVN_REV" != "" ]; then
+ SVN_REV_ARG="-r$LLVM_SVN_REV"
+ echo "Checking out svn revision r$LLVM_SVN_REV."
+else
+ SVN_REV_ARG=""
+ echo "Checking out latest svn revision."
+fi
+
+# Get the sources from svn.
+echo "Checking out sources from git"
+
+for LLVM_PROJECT in $LLVM_PROJECTS; do
+ if [ "$LLVM_PROJECT" == "llvm" ]; then
+ CHECKOUT_DIR="$SOURCE_DIR"
+ elif [ "$LLVM_PROJECT" == "libcxx" ] || [ "$LLVM_PROJECT" == "libcxxabi" ] || [ "$LLVM_PROJECT" == "compiler-rt" ]; then
+ CHECKOUT_DIR="$SOURCE_DIR/projects/$LLVM_PROJECT"
+ elif [ "$LLVM_PROJECT" == "clang" ]; then
+ CHECKOUT_DIR="$SOURCE_DIR/tools/clang"
+ elif [ "$LLVM_PROJECT" == "clang-tools-extra" ]; then
+ CHECKOUT_DIR="$SOURCE_DIR/tools/clang/tools/extra"
+ else
+ CHECKOUT_DIR="$SOURCE_DIR/$LLVM_PROJECT"
+ fi
+
+ echo "Checking out https://git.llvm.org/git/$LLVM_PROJECT to $CHECKOUT_DIR"
+ git clone --depth=1 $GIT_BRANCH_ARG \
+ "https://git.llvm.org/git/$LLVM_PROJECT.git" \
+ "$CHECKOUT_DIR"
+done
+
+echo "Done"
diff --git a/utils/docker/scripts/docker_start_buildbots.sh b/utils/docker/scripts/docker_start_buildbots.sh
new file mode 100755
index 000000000000..f47ddcd2481f
--- /dev/null
+++ b/utils/docker/scripts/docker_start_buildbots.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -x
+
+# Update the libc++ sources in the image in order to use the most recent version of
+# run_buildbots.sh
+cd /libcxx
+git pull
+/libcxx/utils/docker/scripts/run_buildbot.sh "$@"
diff --git a/utils/docker/scripts/install_clang_packages.sh b/utils/docker/scripts/install_clang_packages.sh
new file mode 100755
index 000000000000..fabee0e81472
--- /dev/null
+++ b/utils/docker/scripts/install_clang_packages.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+#===- libcxx/utils/docker/scripts/install_clang_package.sh -----------------===//
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===-----------------------------------------------------------------------===//
+
+set -e
+
+function show_usage() {
+ cat << EOF
+Usage: install_clang_package.sh [options]
+
+Install
+Available options:
+ -h|--help show this help message
+ --version the numeric version of the package to use.
+EOF
+}
+
+VERSION=""
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --version)
+ shift
+ VERSION="$1"
+ shift
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown option: $1"
+ exit 1
+ esac
+done
+
+
+
+curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
+add-apt-repository -s "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs) main"
+apt-get update
+apt-get install -y --no-install-recommends clang
+
+echo "Testing clang version..."
+clang --version
+
+echo "Testing clang++ version..."
+clang++ --version
+
+# Figure out the libc++ and libc++abi package versions that we want.
+if [ "$VERSION" == "" ]; then
+ VERSION="$(apt-cache search 'libc\+\+-[0-9]-dev' | awk '{print $1}' | awk -F- '{print $2}')"
+ echo "Installing version '$VERSION'"
+fi
+
+apt-get install -y --no-install-recommends "libc++-$VERSION-dev" "libc++abi-$VERSION-dev"
+
+echo "Done"
diff --git a/utils/docker/scripts/run_buildbot.sh b/utils/docker/scripts/run_buildbot.sh
new file mode 100755
index 000000000000..45f5a1cf6bfa
--- /dev/null
+++ b/utils/docker/scripts/run_buildbot.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+set -x
+
+BOT_DIR=/b
+BOT_NAME=$1
+BOT_PASS=$2
+
+mkdir -p $BOT_DIR
+
+#curl "https://repo.stackdriver.com/stack-install.sh" | bash -s -- --write-gcm
+
+apt-get update -y
+apt-get upgrade -y
+
+# FIXME(EricWF): Remove this hack. It's only in place to temporarily fix linking libclang_rt from the
+# debian packages.
+# WARNING: If you're not a buildbot, DO NOT RUN!
+apt-get install lld-8
+rm /usr/bin/ld
+ln -s /usr/bin/lld-8 /usr/bin/ld
+
+systemctl set-property buildslave.service TasksMax=100000
+
+buildslave stop $BOT_DIR
+
+chown buildbot:buildbot $BOT_DIR
+
+echo "Connecting as $BOT_NAME"
+buildslave create-slave --allow-shutdown=signal $BOT_DIR lab.llvm.org:9990 $BOT_NAME $BOT_PASS
+
+echo "Eric Fiselier <ericwf@google.com>" > $BOT_DIR/info/admin
+
+{
+ uname -a | head -n1
+ cmake --version | head -n1
+ g++ --version | head -n1
+ ld --version | head -n1
+ date
+ lscpu
+} > $BOT_DIR/info/host
+
+echo "SLAVE_RUNNER=/usr/bin/buildslave
+SLAVE_ENABLED[1]=\"1\"
+SLAVE_NAME[1]=\"buildslave1\"
+SLAVE_USER[1]=\"buildbot\"
+SLAVE_BASEDIR[1]=\"$BOT_DIR\"
+SLAVE_OPTIONS[1]=\"\"
+SLAVE_PREFIXCMD[1]=\"\"" > /etc/default/buildslave
+
+chown -R buildbot:buildbot $BOT_DIR
+systemctl daemon-reload
+service buildslave restart
+
+sleep 30
+cat $BOT_DIR/twistd.log
+grep "slave is ready" $BOT_DIR/twistd.log || shutdown now
+
+# GCE can restart instance after 24h in the middle of the build.
+# Gracefully restart before that happen.
+sleep 72000
+while pkill -SIGHUP buildslave; do sleep 5; done;
+shutdown now \ No newline at end of file
diff --git a/utils/google-benchmark/.clang-format b/utils/google-benchmark/.clang-format
new file mode 100644
index 000000000000..4b3f13fa55e1
--- /dev/null
+++ b/utils/google-benchmark/.clang-format
@@ -0,0 +1,5 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+...
+
diff --git a/utils/google-benchmark/.gitignore b/utils/google-benchmark/.gitignore
index 3c1b4f2183ed..8c30e28f53a0 100644
--- a/utils/google-benchmark/.gitignore
+++ b/utils/google-benchmark/.gitignore
@@ -6,6 +6,7 @@
*.dylib
*.cmake
!/cmake/*.cmake
+!/test/AssemblyTests.cmake
*~
*.pyc
__pycache__
@@ -41,6 +42,17 @@ build.ninja
install_manifest.txt
rules.ninja
+# bazel output symlinks.
+bazel-*
+
# out-of-source build top-level folders.
build/
_build/
+build*/
+
+# in-source dependencies
+/googletest/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+CMakeSettings.json
diff --git a/utils/google-benchmark/.travis-libcxx-setup.sh b/utils/google-benchmark/.travis-libcxx-setup.sh
new file mode 100644
index 000000000000..a591743c6a6b
--- /dev/null
+++ b/utils/google-benchmark/.travis-libcxx-setup.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+# Install a newer CMake version
+curl -sSL https://cmake.org/files/v3.6/cmake-3.6.1-Linux-x86_64.sh -o install-cmake.sh
+chmod +x install-cmake.sh
+sudo ./install-cmake.sh --prefix=/usr/local --skip-license
+
+# Checkout LLVM sources
+git clone --depth=1 https://github.com/llvm-mirror/llvm.git llvm-source
+git clone --depth=1 https://github.com/llvm-mirror/libcxx.git llvm-source/projects/libcxx
+git clone --depth=1 https://github.com/llvm-mirror/libcxxabi.git llvm-source/projects/libcxxabi
+
+# Setup libc++ options
+if [ -z "$BUILD_32_BITS" ]; then
+ export BUILD_32_BITS=OFF && echo disabling 32 bit build
+fi
+
+# Build and install libc++ (Use unstable ABI for better sanitizer coverage)
+mkdir llvm-build && cd llvm-build
+cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr \
+ -DLIBCXX_ABI_UNSTABLE=ON \
+ -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \
+ -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \
+ ../llvm-source
+make cxx -j2
+sudo make install-cxxabi install-cxx
+cd ../
diff --git a/utils/google-benchmark/.travis.yml b/utils/google-benchmark/.travis.yml
new file mode 100644
index 000000000000..4625dfb0878f
--- /dev/null
+++ b/utils/google-benchmark/.travis.yml
@@ -0,0 +1,199 @@
+sudo: required
+dist: trusty
+language: cpp
+
+env:
+ global:
+ - /usr/local/bin:$PATH
+
+matrix:
+ include:
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - lcov
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Coverage
+ - compiler: gcc
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Debug
+ - compiler: gcc
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Release
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - g++-multilib
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Debug BUILD_32_BITS=ON
+ - compiler: gcc
+ addons:
+ apt:
+ packages:
+ - g++-multilib
+ env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Release BUILD_32_BITS=ON
+ - compiler: gcc
+ env:
+ - INSTALL_GCC6_FROM_PPA=1
+ - COMPILER=g++-6 C_COMPILER=gcc-6 BUILD_TYPE=Debug
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-fno-omit-frame-pointer -g -O2 -fsanitize=undefined,address -fuse-ld=gold"
+ - compiler: clang
+ env: COMPILER=clang++ C_COMPILER=clang BUILD_TYPE=Debug
+ - compiler: clang
+ env: COMPILER=clang++ C_COMPILER=clang BUILD_TYPE=Release
+ # Clang w/ libc++
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1
+ - EXTRA_FLAGS="-stdlib=libc++"
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release
+ - LIBCXX_BUILD=1
+ - EXTRA_FLAGS="-stdlib=libc++"
+ # Clang w/ 32bit libc++
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ - clang-3.8
+ - g++-multilib
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-stdlib=libc++ -m32"
+ # Clang w/ 32bit libc++
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ - clang-3.8
+ - g++-multilib
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release
+ - LIBCXX_BUILD=1
+ - BUILD_32_BITS=ON
+ - EXTRA_FLAGS="-stdlib=libc++ -m32"
+ # Clang w/ libc++, ASAN, UBSAN
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER="Undefined;Address"
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-stdlib=libc++ -g -O2 -fno-omit-frame-pointer -fsanitize=undefined,address -fno-sanitize-recover=all"
+ - UBSAN_OPTIONS=print_stacktrace=1
+ # Clang w/ libc++ and MSAN
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER=MemoryWithOrigins
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-stdlib=libc++ -g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins"
+ # Clang w/ libc++ and MSAN
+ - compiler: clang
+ addons:
+ apt:
+ packages:
+ clang-3.8
+ env:
+ - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=RelWithDebInfo
+ - LIBCXX_BUILD=1 LIBCXX_SANITIZER=Thread
+ - ENABLE_SANITIZER=1
+ - EXTRA_FLAGS="-stdlib=libc++ -g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all"
+ - os: osx
+ osx_image: xcode8.3
+ compiler: clang
+ env:
+ - COMPILER=clang++ BUILD_TYPE=Debug
+ - os: osx
+ osx_image: xcode8.3
+ compiler: clang
+ env:
+ - COMPILER=clang++ BUILD_TYPE=Release
+ - os: osx
+ osx_image: xcode8.3
+ compiler: clang
+ env:
+ - COMPILER=clang++ BUILD_TYPE=Release BUILD_32_BITS=ON
+ - os: osx
+ osx_image: xcode8.3
+ compiler: gcc
+ env:
+ - COMPILER=g++-7 C_COMPILER=gcc-7 BUILD_TYPE=Debug
+
+before_script:
+ - if [ -n "${LIBCXX_BUILD}" ]; then
+ source .travis-libcxx-setup.sh;
+ fi
+ - if [ -n "${ENABLE_SANITIZER}" ]; then
+ export EXTRA_OPTIONS="-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF";
+ else
+ export EXTRA_OPTIONS="";
+ fi
+ - mkdir -p build && cd build
+
+before_install:
+ - if [ -z "$BUILD_32_BITS" ]; then
+ export BUILD_32_BITS=OFF && echo disabling 32 bit build;
+ fi
+ - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then
+ sudo add-apt-repository -y "ppa:ubuntu-toolchain-r/test";
+ sudo apt-get update --option Acquire::Retries=100 --option Acquire::http::Timeout="60";
+ fi
+
+install:
+ - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then
+ travis_wait sudo -E apt-get -yq --no-install-suggests --no-install-recommends install g++-6;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "linux" -a "${BUILD_32_BITS}" == "OFF" ]; then
+ travis_wait sudo -E apt-get -y --no-install-suggests --no-install-recommends install llvm-3.9-tools;
+ sudo cp /usr/lib/llvm-3.9/bin/FileCheck /usr/local/bin/;
+ fi
+ - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then
+ PATH=~/.local/bin:${PATH};
+ pip install --user --upgrade pip;
+ travis_wait pip install --user cpp-coveralls;
+ fi
+ - if [ "${C_COMPILER}" == "gcc-7" -a "${TRAVIS_OS_NAME}" == "osx" ]; then
+ rm -f /usr/local/include/c++;
+ brew update;
+ travis_wait brew install gcc@7;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
+ sudo apt-get update -qq;
+ sudo apt-get install -qq unzip;
+ wget https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-linux-x86_64.sh --output-document bazel-installer.sh;
+ travis_wait sudo bash bazel-installer.sh;
+ fi
+ - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
+ curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/0.10.1/bazel-0.10.1-installer-darwin-x86_64.sh;
+ travis_wait sudo bash bazel-installer.sh;
+ fi
+
+script:
+ - cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_BUILD_32_BITS=${BUILD_32_BITS} ${EXTRA_OPTIONS} ..
+ - make
+ - ctest -C ${BUILD_TYPE} --output-on-failure
+ - bazel test -c dbg --define google_benchmark.have_regex=posix --announce_rc --verbose_failures --test_output=errors --keep_going //test/...
+
+after_success:
+ - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then
+ coveralls --include src --include include --gcov-options '\-lp' --root .. --build-root .;
+ fi
diff --git a/utils/google-benchmark/.ycm_extra_conf.py b/utils/google-benchmark/.ycm_extra_conf.py
new file mode 100644
index 000000000000..5649ddcc749f
--- /dev/null
+++ b/utils/google-benchmark/.ycm_extra_conf.py
@@ -0,0 +1,115 @@
+import os
+import ycm_core
+
+# These are the compilation flags that will be used in case there's no
+# compilation database set (by default, one is not set).
+# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
+flags = [
+'-Wall',
+'-Werror',
+'-pedantic-errors',
+'-std=c++0x',
+'-fno-strict-aliasing',
+'-O3',
+'-DNDEBUG',
+# ...and the same thing goes for the magic -x option which specifies the
+# language that the files to be compiled are written in. This is mostly
+# relevant for c++ headers.
+# For a C project, you would set this to 'c' instead of 'c++'.
+'-x', 'c++',
+'-I', 'include',
+'-isystem', '/usr/include',
+'-isystem', '/usr/local/include',
+]
+
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = ''
+
+if os.path.exists( compilation_database_folder ):
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
+
+SOURCE_EXTENSIONS = [ '.cc' ]
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
+ if not working_directory:
+ return list( flags )
+ new_flags = []
+ make_next_absolute = False
+ path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith( '/' ):
+ new_flag = os.path.join( working_directory, flag )
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith( path_flag ):
+ path = flag[ len( path_flag ): ]
+ new_flag = path_flag + os.path.join( working_directory, path )
+ break
+
+ if new_flag:
+ new_flags.append( new_flag )
+ return new_flags
+
+
+def IsHeaderFile( filename ):
+ extension = os.path.splitext( filename )[ 1 ]
+ return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
+
+
+def GetCompilationInfoForFile( filename ):
+ # The compilation_commands.json file generated by CMake does not have entries
+ # for header files. So we do our best by asking the db for flags for a
+ # corresponding source file, if any. If one exists, the flags for that file
+ # should be good enough.
+ if IsHeaderFile( filename ):
+ basename = os.path.splitext( filename )[ 0 ]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists( replacement_file ):
+ compilation_info = database.GetCompilationInfoForFile(
+ replacement_file )
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile( filename )
+
+
+def FlagsForFile( filename, **kwargs ):
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile( filename )
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_ )
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }
diff --git a/utils/google-benchmark/AUTHORS b/utils/google-benchmark/AUTHORS
index daea1f66f07f..09e2e0551adf 100644
--- a/utils/google-benchmark/AUTHORS
+++ b/utils/google-benchmark/AUTHORS
@@ -36,6 +36,7 @@ Maxim Vafin <maxvafin@gmail.com>
MongoDB Inc.
Nick Hutchinson <nshutchinson@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
+Ori Livneh <ori.livneh@gmail.com>
Paul Redmond <paul.redmond@gmail.com>
Radoslav Yovchev <radoslav.tm@gmail.com>
Roman Lebedev <lebedev.ri@gmail.com>
diff --git a/utils/google-benchmark/CMakeLists.txt b/utils/google-benchmark/CMakeLists.txt
index 8ddacabb6e0a..310c7ee9f6b2 100644
--- a/utils/google-benchmark/CMakeLists.txt
+++ b/utils/google-benchmark/CMakeLists.txt
@@ -16,7 +16,11 @@ option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF)
option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library." OFF)
-option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
+if(NOT MSVC)
+ option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
+else()
+ set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL "Build a 32 bit version of the library - unsupported when using MSVC)" FORCE)
+endif()
option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
@@ -75,7 +79,7 @@ get_git_version(GIT_VERSION)
# Tell the user what versions we are using
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${GIT_VERSION})
-message("-- Version: ${VERSION}")
+message(STATUS "Version: ${VERSION}")
# The version of the libraries
set(GENERIC_LIB_VERSION ${VERSION})
@@ -90,7 +94,7 @@ if (BENCHMARK_BUILD_32_BITS)
add_required_cxx_compiler_flag(-m32)
endif()
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+if (MSVC)
# Turn compiler warnings up to 11
string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
@@ -99,6 +103,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
add_cxx_compiler_flag(-EHs-)
add_cxx_compiler_flag(-EHa-)
+ add_definitions(-D_HAS_EXCEPTIONS=0)
endif()
# Link time optimisation
if (BENCHMARK_ENABLE_LTO)
@@ -163,7 +168,7 @@ else()
endif()
# ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden
# (because of deprecated overload)
- add_cxx_compiler_flag(-wd654)
+ add_cxx_compiler_flag(-wd654)
add_cxx_compiler_flag(-Wthread-safety)
if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
cxx_feature_check(THREAD_SAFETY_ATTRIBUTES)
@@ -189,7 +194,7 @@ else()
if (GCC_RANLIB)
set(CMAKE_RANLIB ${GCC_RANLIB})
endif()
- elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+ elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
include(llvm-toolchain)
endif()
endif()
@@ -214,12 +219,12 @@ else()
endif()
if (BENCHMARK_USE_LIBCXX)
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_cxx_compiler_flag(-stdlib=libc++)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
add_cxx_compiler_flag(-nostdinc++)
- message("libc++ header path must be manually specified using CMAKE_CXX_FLAGS")
+ message(WARNING "libc++ header path must be manually specified using CMAKE_CXX_FLAGS")
# Adding -nodefaultlibs directly to CMAKE_<TYPE>_LINKER_FLAGS will break
# configuration checks such as 'find_package(Threads)'
list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)
diff --git a/utils/google-benchmark/CONTRIBUTORS b/utils/google-benchmark/CONTRIBUTORS
index 2ff2f2a8fa0f..ee74ff886c0c 100644
--- a/utils/google-benchmark/CONTRIBUTORS
+++ b/utils/google-benchmark/CONTRIBUTORS
@@ -27,6 +27,7 @@ Arne Beer <arne@twobeer.de>
Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com>
Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com>
Christopher Seymour <chris.j.seymour@hotmail.com>
+Cyrille Faucheux <cyrille.faucheux@gmail.com>
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
Deniz Evrenci <denizevrenci@gmail.com>
Dominic Hamon <dma@stripysock.com> <dominic@google.com>
@@ -50,6 +51,7 @@ Matt Clarkson <mattyclarkson@gmail.com>
Maxim Vafin <maxvafin@gmail.com>
Nick Hutchinson <nshutchinson@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
+Ori Livneh <ori.livneh@gmail.com>
Pascal Leroy <phl@google.com>
Paul Redmond <paul.redmond@gmail.com>
Pierre Phaneuf <pphaneuf@google.com>
diff --git a/utils/google-benchmark/README.md b/utils/google-benchmark/README.md
index 80e69f6e10de..858ea2334ef5 100644
--- a/utils/google-benchmark/README.md
+++ b/utils/google-benchmark/README.md
@@ -6,11 +6,9 @@
A library to support the benchmarking of functions, similar to unit-tests.
-Discussion group: https://groups.google.com/d/forum/benchmark-discuss
+[Discussion group](https://groups.google.com/d/forum/benchmark-discuss)
-IRC channel: https://freenode.net #googlebenchmark
-
-[Known issues and common problems](#known-issues)
+IRC channel: [freenode](https://freenode.net) #googlebenchmark
[Additional Tooling Documentation](docs/tools.md)
@@ -47,11 +45,10 @@ to `CMAKE_ARGS`.
For Ubuntu and Debian Based System
-First make sure you have git and cmake installed (If not please install it)
+First make sure you have git and cmake installed (If not please install them)
```
-sudo apt-get install git
-sudo apt-get install cmake
+sudo apt-get install git cmake
```
Now, let's clone the repository and build it
@@ -59,22 +56,20 @@ Now, let's clone the repository and build it
```
git clone https://github.com/google/benchmark.git
cd benchmark
-git clone https://github.com/google/googletest.git
+# If you want to build tests and don't use BENCHMARK_DOWNLOAD_DEPENDENCIES, then
+# git clone https://github.com/google/googletest.git
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RELEASE
make
```
-We need to install the library globally now
+If you need to install the library globally
```
sudo make install
```
-Now you have google/benchmark installed in your machine
-Note: Don't forget to link to pthread library while building
-
## Stable and Experimental Library Versions
The main branch contains the latest stable version of the benchmarking library;
@@ -87,15 +82,16 @@ to use, test, and provide feedback on the new features are encouraged to try
this branch. However, this branch provides no stability guarantees and reserves
the right to change and break the API at any time.
-## Prerequisite knowledge
-
-Before attempting to understand this framework one should ideally have some familiarity with the structure and format of the Google Test framework, upon which it is based. Documentation for Google Test, including a "Getting Started" (primer) guide, is available here:
-https://github.com/google/googletest/blob/master/googletest/docs/primer.md
+## Further knowledge
+It may help to read the [Google Test documentation](https://github.com/google/googletest/blob/master/googletest/docs/primer.md)
+as some of the structural aspects of the APIs are similar.
## Example usage
### Basic usage
-Define a function that executes the code to be measured.
+Define a function that executes the code to be measured, register it as a
+benchmark function using the `BENCHMARK` macro, and ensure an appropriate `main`
+function is available:
```c++
#include <benchmark/benchmark.h>
@@ -123,7 +119,23 @@ Don't forget to inform your linker to add benchmark library e.g. through
`BENCHMARK_MAIN();` at the end of the source file and link against
`-lbenchmark_main` to get the same default behavior.
-The benchmark library will reporting the timing for the code within the `for(...)` loop.
+The benchmark library will measure and report the timing for code within the
+`for(...)` loop.
+
+#### Platform-specific libraries
+When the library is built using GCC it is necessary to link with the pthread
+library due to how GCC implements `std::thread`. Failing to link to pthread will
+lead to runtime exceptions (unless you're using libc++), not linker errors. See
+[issue #67](https://github.com/google/benchmark/issues/67) for more details. You
+can link to pthread by adding `-pthread` to your linker command. Note, you can
+also use `-lpthread`, but there are potential issues with ordering of command
+line parameters if you use that.
+
+If you're running benchmarks on Windows, the shlwapi library (`-lshlwapi`) is
+also required.
+
+If you're running benchmarks on solaris, you'll want the kstat library linked in
+too (`-lkstat`).
### Passing arguments
Sometimes a family of benchmarks can be implemented with just one routine that
@@ -243,7 +255,7 @@ that might be used to customize high-order term calculation.
```c++
BENCHMARK(BM_StringCompare)->RangeMultiplier(2)
- ->Range(1<<10, 1<<18)->Complexity([](int n)->double{return n; });
+ ->Range(1<<10, 1<<18)->Complexity([](int64_t n)->double{return n; });
```
### Templated benchmarks
@@ -252,7 +264,7 @@ messages of size `sizeof(v)` `range_x` times. It also outputs throughput in the
absence of multiprogramming.
```c++
-template <class Q> int BM_Sequential(benchmark::State& state) {
+template <class Q> void BM_Sequential(benchmark::State& state) {
Q q;
typename Q::value_type v;
for (auto _ : state) {
@@ -416,6 +428,26 @@ BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime();
Without `UseRealTime`, CPU time is used by default.
+## Controlling timers
+Normally, the entire duration of the work loop (`for (auto _ : state) {}`)
+is measured. But sometimes, it is nessesary to do some work inside of
+that loop, every iteration, but without counting that time to the benchmark time.
+That is possible, althought it is not recommended, since it has high overhead.
+
+```c++
+static void BM_SetInsert_With_Timer_Control(benchmark::State& state) {
+ std::set<int> data;
+ for (auto _ : state) {
+ state.PauseTiming(); // Stop timers. They will not count until they are resumed.
+ data = ConstructRandomSet(state.range(0)); // Do something that should not be measured
+ state.ResumeTiming(); // And resume timers. They are now counting again.
+ // The rest will be measured.
+ for (int j = 0; j < state.range(1); ++j)
+ data.insert(RandomNumber());
+ }
+}
+BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}});
+```
## Manual timing
For benchmarking something for which neither CPU time nor real-time are
@@ -522,15 +554,7 @@ order to manually set the time unit, you can specify it manually:
BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
```
-## Controlling number of iterations
-In all cases, the number of iterations for which the benchmark is run is
-governed by the amount of time the benchmark takes. Concretely, the number of
-iterations is at least one, not more than 1e9, until CPU time is greater than
-the minimum time, or the wallclock time is 5x minimum time. The minimum time is
-set as a flag `--benchmark_min_time` or per benchmark by calling `MinTime` on
-the registered benchmark object.
-
-## Reporting the mean, median and standard deviation by repeated benchmarks
+### Reporting the mean, median and standard deviation by repeated benchmarks
By default each benchmark is run once and that single result is reported.
However benchmarks are often noisy and a single result may not be representative
of the overall behavior. For this reason it's possible to repeatedly rerun the
@@ -541,12 +565,20 @@ The number of runs of each benchmark is specified globally by the
`Repetitions` on the registered benchmark object. When a benchmark is run more
than once the mean, median and standard deviation of the runs will be reported.
-Additionally the `--benchmark_report_aggregates_only={true|false}` flag or
-`ReportAggregatesOnly(bool)` function can be used to change how repeated tests
-are reported. By default the result of each repeated run is reported. When this
-option is `true` only the mean, median and standard deviation of the runs is reported.
-Calling `ReportAggregatesOnly(bool)` on a registered benchmark object overrides
-the value of the flag for that benchmark.
+Additionally the `--benchmark_report_aggregates_only={true|false}`,
+`--benchmark_display_aggregates_only={true|false}` flags or
+`ReportAggregatesOnly(bool)`, `DisplayAggregatesOnly(bool)` functions can be
+used to change how repeated tests are reported. By default the result of each
+repeated run is reported. When `report aggregates only` option is `true`,
+only the aggregates (i.e. mean, median and standard deviation, maybe complexity
+measurements if they were requested) of the runs is reported, to both the
+reporters - standard output (console), and the file.
+However when only the `display aggregates only` option is `true`,
+only the aggregates are displayed in the standard output, while the file
+output still contains everything.
+Calling `ReportAggregatesOnly(bool)` / `DisplayAggregatesOnly(bool)` on a
+registered benchmark object overrides the value of the appropriate flag for that
+benchmark.
## User-defined statistics for repeated benchmarks
While having mean, median and standard deviation is nice, this may not be
@@ -653,9 +685,12 @@ In multithreaded benchmarks, each counter is set on the calling thread only.
When the benchmark finishes, the counters from each thread will be summed;
the resulting sum is the value which will be shown for the benchmark.
-The `Counter` constructor accepts two parameters: the value as a `double`
-and a bit flag which allows you to show counters as rates and/or as
-per-thread averages:
+The `Counter` constructor accepts three parameters: the value as a `double`
+; a bit flag which allows you to show counters as rates, and/or as per-thread
+iteration, and/or as per-thread averages, and/or iteration invariants;
+and a flag specifying the 'unit' - i.e. is 1k a 1000 (default,
+`benchmark::Counter::OneK::kIs1000`), or 1024
+(`benchmark::Counter::OneK::kIs1024`)?
```c++
// sets a simple counter
@@ -671,6 +706,9 @@ per-thread averages:
// There's also a combined flag:
state.counters["FooAvgRate"] = Counter(numFoos,benchmark::Counter::kAvgThreadsRate);
+
+ // This says that we process with the rate of state.range(0) bytes every iteration:
+ state.counters["BytesProcessed"] = Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024);
```
When you're compiling in C++11 mode or later you can use `insert()` with
@@ -810,8 +848,29 @@ BM_memcpy/32 12 ns 12 ns 54687500
BM_memcpy/32k 1834 ns 1837 ns 357143
```
+## Runtime and reporting considerations
+When the benchmark binary is executed, each benchmark function is run serially.
+The number of iterations to run is determined dynamically by running the
+benchmark a few times and measuring the time taken and ensuring that the
+ultimate result will be statistically stable. As such, faster benchmark
+functions will be run for more iterations than slower benchmark functions, and
+the number of iterations is thus reported.
+
+In all cases, the number of iterations for which the benchmark is run is
+governed by the amount of time the benchmark takes. Concretely, the number of
+iterations is at least one, not more than 1e9, until CPU time is greater than
+the minimum time, or the wallclock time is 5x minimum time. The minimum time is
+set per benchmark by calling `MinTime` on the registered benchmark object.
+
+Average timings are then reported over the iterations run. If multiple
+repetitions are requested using the `--benchmark_repetitions` command-line
+option, or at registration time, the benchmark function will be run several
+times and statistical results across these repetitions will also be reported.
+
+As well as the per-benchmark entries, a preamble in the report will include
+information about the machine on which the benchmarks are run.
-## Output Formats
+### Output Formats
The library supports multiple output formats. Use the
`--benchmark_format=<console|json|csv>` flag to set the format type. `console`
is the default format.
@@ -879,14 +938,19 @@ name,iterations,real_time,cpu_time,bytes_per_second,items_per_second,label
"BM_SetInsert/1024/10",106365,17238.4,8421.53,4.74973e+06,1.18743e+06,
```
-## Output Files
+### Output Files
The library supports writing the output of the benchmark to a file specified
by `--benchmark_out=<filename>`. The format of the output can be specified
using `--benchmark_out_format={json|console|csv}`. Specifying
`--benchmark_out` does not suppress the console output.
+## Result comparison
+
+It is possible to compare the benchmarking results. See [Additional Tooling Documentation](docs/tools.md)
+
## Debug vs Release
-By default, benchmark builds as a debug library. You will see a warning in the output when this is the case. To build it as a release library instead, use:
+By default, benchmark builds as a debug library. You will see a warning in the
+output when this is the case. To build it as a release library instead, use:
```
cmake -DCMAKE_BUILD_TYPE=Release
@@ -898,16 +962,11 @@ To enable link-time optimisation, use
cmake -DCMAKE_BUILD_TYPE=Release -DBENCHMARK_ENABLE_LTO=true
```
-If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake cache variables, if autodetection fails.
-If you are using clang, you may need to set `LLVMAR_EXECUTABLE`, `LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
-
-## Linking against the library
+If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake
+cache variables, if autodetection fails.
-When the library is built using GCC it is necessary to link with `-pthread`,
-due to how GCC implements `std::thread`.
-
-For GCC 4.x failing to link to pthreads will lead to runtime exceptions, not linker errors.
-See [issue #67](https://github.com/google/benchmark/issues/67) for more details.
+If you are using clang, you may need to set `LLVMAR_EXECUTABLE`,
+`LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
## Compiler Support
@@ -937,14 +996,3 @@ sudo cpupower frequency-set --governor performance
./mybench
sudo cpupower frequency-set --governor powersave
```
-
-# Known Issues
-
-### Windows with CMake
-
-* Users must manually link `shlwapi.lib`. Failure to do so may result
-in unresolved symbols.
-
-### Solaris
-
-* Users must explicitly link with kstat library (-lkstat compilation flag).
diff --git a/utils/google-benchmark/WORKSPACE b/utils/google-benchmark/WORKSPACE
new file mode 100644
index 000000000000..54734f1ea55e
--- /dev/null
+++ b/utils/google-benchmark/WORKSPACE
@@ -0,0 +1,7 @@
+workspace(name = "com_github_google_benchmark")
+
+http_archive(
+ name = "com_google_googletest",
+ urls = ["https://github.com/google/googletest/archive/3f0cf6b62ad1eb50d8736538363d3580dd640c3e.zip"],
+ strip_prefix = "googletest-3f0cf6b62ad1eb50d8736538363d3580dd640c3e",
+)
diff --git a/utils/google-benchmark/appveyor.yml b/utils/google-benchmark/appveyor.yml
new file mode 100644
index 000000000000..cf240190bea6
--- /dev/null
+++ b/utils/google-benchmark/appveyor.yml
@@ -0,0 +1,50 @@
+version: '{build}'
+
+image: Visual Studio 2017
+
+configuration:
+ - Debug
+ - Release
+
+environment:
+ matrix:
+ - compiler: msvc-15-seh
+ generator: "Visual Studio 15 2017"
+
+ - compiler: msvc-15-seh
+ generator: "Visual Studio 15 2017 Win64"
+
+ - compiler: msvc-14-seh
+ generator: "Visual Studio 14 2015"
+
+ - compiler: msvc-14-seh
+ generator: "Visual Studio 14 2015 Win64"
+
+ - compiler: gcc-5.3.0-posix
+ generator: "MinGW Makefiles"
+ cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+
+matrix:
+ fast_finish: true
+
+install:
+ # git bash conflicts with MinGW makefiles
+ - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%")
+ - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%")
+
+build_script:
+ - md _build -Force
+ - cd _build
+ - echo %configuration%
+ - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ..
+ - cmake --build . --config %configuration%
+
+test_script:
+ - ctest -c %configuration% --timeout 300 --output-on-failure
+
+artifacts:
+ - path: '_build/CMakeFiles/*.log'
+ name: logs
+ - path: '_build/Testing/**/*.xml'
+ name: test_results
diff --git a/utils/google-benchmark/cmake/CXXFeatureCheck.cmake b/utils/google-benchmark/cmake/CXXFeatureCheck.cmake
index c4c4d660f1eb..99b56dd62390 100644
--- a/utils/google-benchmark/cmake/CXXFeatureCheck.cmake
+++ b/utils/google-benchmark/cmake/CXXFeatureCheck.cmake
@@ -28,7 +28,7 @@ function(cxx_feature_check FILE)
endif()
if (NOT DEFINED COMPILE_${FEATURE})
- message("-- Performing Test ${FEATURE}")
+ message(STATUS "Performing Test ${FEATURE}")
if(CMAKE_CROSSCOMPILING)
try_compile(COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
@@ -42,7 +42,7 @@ function(cxx_feature_check FILE)
set(RUN_${FEATURE} 1)
endif()
else()
- message("-- Performing Test ${FEATURE}")
+ message(STATUS "Performing Test ${FEATURE}")
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}
@@ -51,14 +51,14 @@ function(cxx_feature_check FILE)
endif()
if(RUN_${FEATURE} EQUAL 0)
- message("-- Performing Test ${FEATURE} -- success")
+ message(STATUS "Performing Test ${FEATURE} -- success")
set(HAVE_${VAR} 1 PARENT_SCOPE)
add_definitions(-DHAVE_${VAR})
else()
if(NOT COMPILE_${FEATURE})
- message("-- Performing Test ${FEATURE} -- failed to compile")
+ message(STATUS "Performing Test ${FEATURE} -- failed to compile")
else()
- message("-- Performing Test ${FEATURE} -- compiled but failed to run")
+ message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
endif()
endif()
endfunction()
diff --git a/utils/google-benchmark/cmake/GetGitVersion.cmake b/utils/google-benchmark/cmake/GetGitVersion.cmake
index 88cebe3a1caa..4f10f226d7a7 100644
--- a/utils/google-benchmark/cmake/GetGitVersion.cmake
+++ b/utils/google-benchmark/cmake/GetGitVersion.cmake
@@ -49,6 +49,6 @@ function(get_git_version var)
set(GIT_VERSION "v0.0.0")
endif()
- message("-- git Version: ${GIT_VERSION}")
+ message(STATUS "git Version: ${GIT_VERSION}")
set(${var} ${GIT_VERSION} PARENT_SCOPE)
endfunction()
diff --git a/utils/google-benchmark/cmake/HandleGTest.cmake b/utils/google-benchmark/cmake/HandleGTest.cmake
index 7ce1a633d65a..b9c14436dbfa 100644
--- a/utils/google-benchmark/cmake/HandleGTest.cmake
+++ b/utils/google-benchmark/cmake/HandleGTest.cmake
@@ -5,7 +5,7 @@ macro(build_external_gtest)
include(ExternalProject)
set(GTEST_FLAGS "")
if (BENCHMARK_USE_LIBCXX)
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
list(APPEND GTEST_FLAGS -stdlib=libc++)
else()
message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++")
@@ -76,11 +76,11 @@ macro(build_external_gtest)
endmacro(build_external_gtest)
if (BENCHMARK_ENABLE_GTEST_TESTS)
- if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/googletest)
- set(GTEST_ROOT "${CMAKE_SOURCE_DIR}/googletest")
+ if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
+ set(GTEST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/googletest")
set(INSTALL_GTEST OFF CACHE INTERNAL "")
set(INSTALL_GMOCK OFF CACHE INTERNAL "")
- add_subdirectory(${CMAKE_SOURCE_DIR}/googletest)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/googletest)
set(GTEST_BOTH_LIBRARIES gtest gmock gmock_main)
foreach(HEADER test mock)
# CMake 2.8 and older don't respect INTERFACE_INCLUDE_DIRECTORIES, so we
diff --git a/utils/google-benchmark/docs/tools.md b/utils/google-benchmark/docs/tools.md
index 70500bd3223c..4a3b2e9bd2c9 100644
--- a/utils/google-benchmark/docs/tools.md
+++ b/utils/google-benchmark/docs/tools.md
@@ -1,84 +1,25 @@
# Benchmark Tools
-## compare_bench.py
-
-The `compare_bench.py` utility which can be used to compare the result of benchmarks.
-The program is invoked like:
-
-``` bash
-$ compare_bench.py <old-benchmark> <new-benchmark> [benchmark options]...
-```
-
-Where `<old-benchmark>` and `<new-benchmark>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
-
-`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
-
-The sample output using the JSON test files under `Inputs/` gives:
-
-``` bash
-$ ./compare_bench.py ./gbench/Inputs/test1_run1.json ./gbench/Inputs/test1_run2.json
-Comparing ./gbench/Inputs/test1_run1.json to ./gbench/Inputs/test1_run2.json
-Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------
-BM_SameTimes +0.0000 +0.0000 10 10 10 10
-BM_2xFaster -0.5000 -0.5000 50 25 50 25
-BM_2xSlower +1.0000 +1.0000 50 100 50 100
-BM_1PercentFaster -0.0100 -0.0100 100 99 100 99
-BM_1PercentSlower +0.0100 +0.0100 100 101 100 101
-BM_10PercentFaster -0.1000 -0.1000 100 90 100 90
-BM_10PercentSlower +0.1000 +0.1000 100 110 100 110
-BM_100xSlower +99.0000 +99.0000 100 10000 100 10000
-BM_100xFaster -0.9900 -0.9900 10000 100 10000 100
-BM_10PercentCPUToTime +0.1000 -0.1000 100 110 100 90
-BM_ThirdFaster -0.3333 -0.3334 100 67 100 67
-BM_BadTimeUnit -0.9000 +0.2000 0 0 0 1
-```
-
-As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
+## compare.py
-When a benchmark executable is run, the raw output from the benchmark is printed in real time to stdout. The sample output using `benchmark/basic_test` for both arguments looks like:
+The `compare.py` can be used to compare the result of benchmarks.
-```
-./compare_bench.py test/basic_test test/basic_test --benchmark_filter=BM_empty.*
-RUNNING: test/basic_test --benchmark_filter=BM_empty.* --benchmark_out=/tmp/tmpN7LF3a
-Run on (8 X 4000 MHz CPU s)
-2017-11-07 23:28:36
----------------------------------------------------------------------
-Benchmark Time CPU Iterations
----------------------------------------------------------------------
-BM_empty 4 ns 4 ns 170178757
-BM_empty/threads:8 1 ns 7 ns 103868920
-BM_empty_stop_start 0 ns 0 ns 1000000000
-BM_empty_stop_start/threads:8 0 ns 0 ns 1403031720
-RUNNING: /test/basic_test --benchmark_filter=BM_empty.* --benchmark_out=/tmp/tmplvrIp8
-Run on (8 X 4000 MHz CPU s)
-2017-11-07 23:28:38
----------------------------------------------------------------------
-Benchmark Time CPU Iterations
----------------------------------------------------------------------
-BM_empty 4 ns 4 ns 169534855
-BM_empty/threads:8 1 ns 7 ns 104188776
-BM_empty_stop_start 0 ns 0 ns 1000000000
-BM_empty_stop_start/threads:8 0 ns 0 ns 1404159424
-Comparing ../build/test/basic_test to ../build/test/basic_test
-Benchmark Time CPU Time Old Time New CPU Old CPU New
----------------------------------------------------------------------------------------------------------------------
-BM_empty -0.0048 -0.0049 4 4 4 4
-BM_empty/threads:8 -0.0123 -0.0054 1 1 7 7
-BM_empty_stop_start -0.0000 -0.0000 0 0 0 0
-BM_empty_stop_start/threads:8 -0.0029 +0.0001 0 0 0 0
+**NOTE**: the utility relies on the scipy package which can be installed using [these instructions](https://www.scipy.org/install.html).
-```
+### Displaying aggregates only
-As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
-Obviously this example doesn't give any useful output, but it's intended to show the output format when 'compare_bench.py' needs to run benchmarks.
+The switch `-a` / `--display_aggregates_only` can be used to control the
+displayment of the normal iterations vs the aggregates. When passed, it will
+be passthrough to the benchmark binaries to be run, and will be accounted for
+in the tool itself; only the aggregates will be displayed, but not normal runs.
+It only affects the display, the separate runs will still be used to calculate
+the U test.
-## compare.py
+### Modes of operation
-The `compare.py` can be used to compare the result of benchmarks.
There are three modes of operation:
-1. Just compare two benchmarks, what `compare_bench.py` did.
+1. Just compare two benchmarks
The program is invoked like:
``` bash
@@ -240,3 +181,19 @@ Benchmark Time CPU Time Old
```
This is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
+
+### U test
+
+If there is a sufficient repetition count of the benchmarks, the tool can do
+a [U Test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), of the
+null hypothesis that it is equally likely that a randomly selected value from
+one sample will be less than or greater than a randomly selected value from a
+second sample.
+
+If the calculated p-value is below this value is lower than the significance
+level alpha, then the result is said to be statistically significant and the
+null hypothesis is rejected. Which in other words means that the two benchmarks
+aren't identical.
+
+**WARNING**: requires **LARGE** (no less than 9) number of repetitions to be
+meaningful!
diff --git a/utils/google-benchmark/include/benchmark/benchmark.h b/utils/google-benchmark/include/benchmark/benchmark.h
index 193fffc4beaa..a0fd7c6e1cad 100644
--- a/utils/google-benchmark/include/benchmark/benchmark.h
+++ b/utils/google-benchmark/include/benchmark/benchmark.h
@@ -241,8 +241,21 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#endif
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
+ #define BENCHMARK_UNREACHABLE() __builtin_unreachable()
+#elif defined(_MSC_VER)
+ #define BENCHMARK_UNREACHABLE() __assume(false)
+#else
+ #define BENCHMARK_UNREACHABLE() ((void)0)
+#endif
+
namespace benchmark {
class BenchmarkReporter;
+class MemoryManager;
void Initialize(int* argc, char** argv);
@@ -255,7 +268,7 @@ bool ReportUnrecognizedArguments(int argc, char** argv);
// of each matching benchmark. Otherwise run each matching benchmark and
// report the results.
//
-// The second and third overload use the specified 'console_reporter' and
+// The second and third overload use the specified 'display_reporter' and
// 'file_reporter' respectively. 'file_reporter' will write to the file
// specified
// by '--benchmark_output'. If '--benchmark_output' is not given the
@@ -263,16 +276,13 @@ bool ReportUnrecognizedArguments(int argc, char** argv);
//
// RETURNS: The number of matching benchmarks.
size_t RunSpecifiedBenchmarks();
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter);
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
+size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
+size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
BenchmarkReporter* file_reporter);
-// If this routine is called, peak memory allocation past this point in the
-// benchmark is reported at the end of the benchmark report line. (It is
-// computed by running the benchmark once with a single iteration and a memory
-// tracer.)
-// TODO(dominic)
-// void MemoryUsage();
+// Register a MemoryManager instance that will be used to collect and report
+// allocation measurements for benchmark runs.
+void RegisterMemoryManager(MemoryManager* memory_manager);
namespace internal {
class Benchmark;
@@ -363,11 +373,20 @@ class Counter {
kAvgIterationsRate = kIsRate | kAvgIterations
};
+ enum OneK {
+ // 1'000 items per 1k
+ kIs1000 = 1000,
+ // 1'024 items per 1k
+ kIs1024 = 1024
+ };
+
double value;
Flags flags;
+ OneK oneK;
BENCHMARK_ALWAYS_INLINE
- Counter(double v = 0., Flags f = kDefaults) : value(v), flags(f) {}
+ Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)
+ : value(v), flags(f), oneK(k) {}
BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; }
BENCHMARK_ALWAYS_INLINE operator double&() { return value; }
@@ -406,22 +425,35 @@ struct Statistics {
std::string name_;
StatisticsFunc* compute_;
- Statistics(std::string name, StatisticsFunc* compute)
+ Statistics(const std::string& name, StatisticsFunc* compute)
: name_(name), compute_(compute) {}
};
namespace internal {
+struct BenchmarkInstance;
class ThreadTimer;
class ThreadManager;
-enum ReportMode
+enum AggregationReportMode
#if defined(BENCHMARK_HAS_CXX11)
: unsigned
#else
#endif
-{ RM_Unspecified, // The mode has not been manually specified
- RM_Default, // The mode is user-specified as default.
- RM_ReportAggregatesOnly };
+{
+ // The mode has not been manually specified
+ ARM_Unspecified = 0,
+ // The mode is user-specified.
+ // This may or may not be set when the following bit-flags are set.
+ ARM_Default = 1U << 0U,
+ // File reporter should only output aggregates.
+ ARM_FileReportAggregatesOnly = 1U << 1U,
+ // Display reporter should only output aggregates
+ ARM_DisplayReportAggregatesOnly = 1U << 2U,
+ // Both reporters should only display aggregates.
+ ARM_ReportAggregatesOnly =
+ ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
+};
+
} // namespace internal
// State is passed to a running Benchmark and contains state for the
@@ -517,16 +549,21 @@ class State {
// Set the number of bytes processed by the current benchmark
// execution. This routine is typically called once at the end of a
- // throughput oriented benchmark. If this routine is called with a
- // value > 0, the report is printed in MB/sec instead of nanoseconds
- // per iteration.
+ // throughput oriented benchmark.
//
// REQUIRES: a benchmark has exited its benchmarking loop.
BENCHMARK_ALWAYS_INLINE
- void SetBytesProcessed(int64_t bytes) { bytes_processed_ = bytes; }
+ void SetBytesProcessed(int64_t bytes) {
+ counters["bytes_per_second"] =
+ Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
+ }
BENCHMARK_ALWAYS_INLINE
- int64_t bytes_processed() const { return bytes_processed_; }
+ int64_t bytes_processed() const {
+ if (counters.find("bytes_per_second") != counters.end())
+ return static_cast<int64_t>(counters.at("bytes_per_second"));
+ return 0;
+ }
// If this routine is called with complexity_n > 0 and complexity report is
// requested for the
@@ -546,10 +583,17 @@ class State {
//
// REQUIRES: a benchmark has exited its benchmarking loop.
BENCHMARK_ALWAYS_INLINE
- void SetItemsProcessed(int64_t items) { items_processed_ = items; }
+ void SetItemsProcessed(int64_t items) {
+ counters["items_per_second"] =
+ Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
+ }
BENCHMARK_ALWAYS_INLINE
- int64_t items_processed() const { return items_processed_; }
+ int64_t items_processed() const {
+ if (counters.find("items_per_second") != counters.end())
+ return static_cast<int64_t>(counters.at("items_per_second"));
+ return 0;
+ }
// If this routine is called, the specified label is printed at the
// end of the benchmark report line for the currently executing
@@ -612,9 +656,6 @@ class State {
private: // items we don't need on the first cache line
std::vector<int64_t> range_;
- int64_t bytes_processed_;
- int64_t items_processed_;
-
int64_t complexity_n_;
public:
@@ -625,12 +666,11 @@ class State {
// Number of threads concurrently executing the benchmark.
const int threads;
- // TODO(EricWF) make me private
+ private:
State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
int n_threads, internal::ThreadTimer* timer,
internal::ThreadManager* manager);
- private:
void StartKeepRunning();
// Implementation of KeepRunning() and KeepRunningBatch().
// is_batch must be true unless n is 1.
@@ -638,7 +678,8 @@ class State {
void FinishKeepRunning();
internal::ThreadTimer* timer_;
internal::ThreadManager* manager_;
- BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
+
+ friend struct internal::BenchmarkInstance;
};
inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {
@@ -827,8 +868,12 @@ class Benchmark {
// Specify if each repetition of the benchmark should be reported separately
// or if only the final statistics should be reported. If the benchmark
// is not repeated then the single result is always reported.
+ // Applies to *ALL* reporters (display and file).
Benchmark* ReportAggregatesOnly(bool value = true);
+ // Same as ReportAggregatesOnly(), but applies to display reporter only.
+ Benchmark* DisplayAggregatesOnly(bool value = true);
+
// If a particular benchmark is I/O bound, runs multiple threads internally or
// if for some reason CPU timings are not representative, call this method. If
// called, the elapsed time will be used to control how many iterations are
@@ -888,9 +933,6 @@ class Benchmark {
virtual void Run(State& state) = 0;
- // Used inside the benchmark implementation
- struct Instance;
-
protected:
explicit Benchmark(const char* name);
Benchmark(Benchmark const&);
@@ -902,7 +944,7 @@ class Benchmark {
friend class BenchmarkFamilies;
std::string name_;
- ReportMode report_mode_;
+ AggregationReportMode aggregation_report_mode_;
std::vector<std::string> arg_names_; // Args for all benchmark runs
std::vector<std::vector<int64_t> > args_; // Args for all benchmark runs
TimeUnit time_unit_;
@@ -1242,6 +1284,7 @@ struct CPUInfo {
double cycles_per_second;
std::vector<CacheInfo> caches;
bool scaling_enabled;
+ std::vector<double> load_avg;
static const CPUInfo& Get();
@@ -1250,6 +1293,15 @@ struct CPUInfo {
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);
};
+//Adding Struct for System Information
+struct SystemInfo {
+ std::string name;
+ static const SystemInfo& Get();
+ private:
+ SystemInfo();
+ BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
+};
+
// Interface for custom benchmark result printers.
// By default, benchmark reports are printed to stdout. However an application
// can control the destination of the reports by calling
@@ -1259,6 +1311,7 @@ class BenchmarkReporter {
public:
struct Context {
CPUInfo const& cpu_info;
+ SystemInfo const& sys_info;
// The number of chars in the longest benchmark name.
size_t name_field_width;
static const char* executable_name;
@@ -1266,23 +1319,30 @@ class BenchmarkReporter {
};
struct Run {
+ enum RunType { RT_Iteration, RT_Aggregate };
+
Run()
- : error_occurred(false),
+ : run_type(RT_Iteration),
+ error_occurred(false),
iterations(1),
time_unit(kNanosecond),
real_accumulated_time(0),
cpu_accumulated_time(0),
- bytes_per_second(0),
- items_per_second(0),
max_heapbytes_used(0),
complexity(oNone),
complexity_lambda(),
complexity_n(0),
report_big_o(false),
report_rms(false),
- counters() {}
-
- std::string benchmark_name;
+ counters(),
+ has_memory_result(false),
+ allocs_per_iter(0.0),
+ max_bytes_used(0) {}
+
+ std::string benchmark_name() const;
+ std::string run_name;
+ RunType run_type; // is this a measurement, or an aggregate?
+ std::string aggregate_name;
std::string report_label; // Empty if not set by benchmark.
bool error_occurred;
std::string error_message;
@@ -1304,10 +1364,6 @@ class BenchmarkReporter {
// accumulated time.
double GetAdjustedCPUTime() const;
- // Zero if not set by benchmark.
- double bytes_per_second;
- double items_per_second;
-
// This is set to 0.0 if memory tracing is not enabled.
double max_heapbytes_used;
@@ -1324,6 +1380,11 @@ class BenchmarkReporter {
bool report_rms;
UserCounters counters;
+
+ // Memory metrics.
+ bool has_memory_result;
+ double allocs_per_iter;
+ int64_t max_bytes_used;
};
// Construct a BenchmarkReporter with the output stream set to 'std::cout'
@@ -1438,6 +1499,29 @@ class BENCHMARK_DEPRECATED_MSG("The CSV Reporter will be removed in a future rel
std::set<std::string> user_counter_names_;
};
+// If a MemoryManager is registered, it can be used to collect and report
+// allocation metrics for a run of the benchmark.
+class MemoryManager {
+ public:
+ struct Result {
+ Result() : num_allocs(0), max_bytes_used(0) {}
+
+ // The number of allocations made in total between Start and Stop.
+ int64_t num_allocs;
+
+ // The peak memory use between Start and Stop.
+ int64_t max_bytes_used;
+ };
+
+ virtual ~MemoryManager() {}
+
+ // Implement this to start recording allocation information.
+ virtual void Start() = 0;
+
+ // Implement this to stop recording and fill out the given Result structure.
+ virtual void Stop(Result* result) = 0;
+};
+
inline const char* GetTimeUnitString(TimeUnit unit) {
switch (unit) {
case kMillisecond:
@@ -1445,9 +1529,9 @@ inline const char* GetTimeUnitString(TimeUnit unit) {
case kMicrosecond:
return "us";
case kNanosecond:
- default:
return "ns";
}
+ BENCHMARK_UNREACHABLE();
}
inline double GetTimeUnitMultiplier(TimeUnit unit) {
@@ -1457,9 +1541,9 @@ inline double GetTimeUnitMultiplier(TimeUnit unit) {
case kMicrosecond:
return 1e6;
case kNanosecond:
- default:
return 1e9;
}
+ BENCHMARK_UNREACHABLE();
}
} // namespace benchmark
diff --git a/utils/google-benchmark/mingw.py b/utils/google-benchmark/mingw.py
new file mode 100644
index 000000000000..706ad559db9c
--- /dev/null
+++ b/utils/google-benchmark/mingw.py
@@ -0,0 +1,320 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+import argparse
+import errno
+import logging
+import os
+import platform
+import re
+import sys
+import subprocess
+import tempfile
+
+try:
+ import winreg
+except ImportError:
+ import _winreg as winreg
+try:
+ import urllib.request as request
+except ImportError:
+ import urllib as request
+try:
+ import urllib.parse as parse
+except ImportError:
+ import urlparse as parse
+
+class EmptyLogger(object):
+ '''
+ Provides an implementation that performs no logging
+ '''
+ def debug(self, *k, **kw):
+ pass
+ def info(self, *k, **kw):
+ pass
+ def warn(self, *k, **kw):
+ pass
+ def error(self, *k, **kw):
+ pass
+ def critical(self, *k, **kw):
+ pass
+ def setLevel(self, *k, **kw):
+ pass
+
+urls = (
+ 'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20'
+ 'targetting%20Win32/Personal%20Builds/mingw-builds/installer/'
+ 'repository.txt',
+ 'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/'
+ 'repository.txt'
+)
+'''
+A list of mingw-build repositories
+'''
+
+def repository(urls = urls, log = EmptyLogger()):
+ '''
+ Downloads and parse mingw-build repository files and parses them
+ '''
+ log.info('getting mingw-builds repository')
+ versions = {}
+ re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files')
+ re_sub = r'http://downloads.sourceforge.net/project/\1'
+ for url in urls:
+ log.debug(' - requesting: %s', url)
+ socket = request.urlopen(url)
+ repo = socket.read()
+ if not isinstance(repo, str):
+ repo = repo.decode();
+ socket.close()
+ for entry in repo.split('\n')[:-1]:
+ value = entry.split('|')
+ version = tuple([int(n) for n in value[0].strip().split('.')])
+ version = versions.setdefault(version, {})
+ arch = value[1].strip()
+ if arch == 'x32':
+ arch = 'i686'
+ elif arch == 'x64':
+ arch = 'x86_64'
+ arch = version.setdefault(arch, {})
+ threading = arch.setdefault(value[2].strip(), {})
+ exceptions = threading.setdefault(value[3].strip(), {})
+ revision = exceptions.setdefault(int(value[4].strip()[3:]),
+ re_sourceforge.sub(re_sub, value[5].strip()))
+ return versions
+
+def find_in_path(file, path=None):
+ '''
+ Attempts to find an executable in the path
+ '''
+ if platform.system() == 'Windows':
+ file += '.exe'
+ if path is None:
+ path = os.environ.get('PATH', '')
+ if type(path) is type(''):
+ path = path.split(os.pathsep)
+ return list(filter(os.path.exists,
+ map(lambda dir, file=file: os.path.join(dir, file), path)))
+
+def find_7zip(log = EmptyLogger()):
+ '''
+ Attempts to find 7zip for unpacking the mingw-build archives
+ '''
+ log.info('finding 7zip')
+ path = find_in_path('7z')
+ if not path:
+ key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip')
+ path, _ = winreg.QueryValueEx(key, 'Path')
+ path = [os.path.join(path, '7z.exe')]
+ log.debug('found \'%s\'', path[0])
+ return path[0]
+
+find_7zip()
+
+def unpack(archive, location, log = EmptyLogger()):
+ '''
+ Unpacks a mingw-builds archive
+ '''
+ sevenzip = find_7zip(log)
+ log.info('unpacking %s', os.path.basename(archive))
+ cmd = [sevenzip, 'x', archive, '-o' + location, '-y']
+ log.debug(' - %r', cmd)
+ with open(os.devnull, 'w') as devnull:
+ subprocess.check_call(cmd, stdout = devnull)
+
+def download(url, location, log = EmptyLogger()):
+ '''
+ Downloads and unpacks a mingw-builds archive
+ '''
+ log.info('downloading MinGW')
+ log.debug(' - url: %s', url)
+ log.debug(' - location: %s', location)
+
+ re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*')
+
+ stream = request.urlopen(url)
+ try:
+ content = stream.getheader('Content-Disposition') or ''
+ except AttributeError:
+ content = stream.headers.getheader('Content-Disposition') or ''
+ matches = re_content.match(content)
+ if matches:
+ filename = matches.group(2)
+ else:
+ parsed = parse.urlparse(stream.geturl())
+ filename = os.path.basename(parsed.path)
+
+ try:
+ os.makedirs(location)
+ except OSError as e:
+ if e.errno == errno.EEXIST and os.path.isdir(location):
+ pass
+ else:
+ raise
+
+ archive = os.path.join(location, filename)
+ with open(archive, 'wb') as out:
+ while True:
+ buf = stream.read(1024)
+ if not buf:
+ break
+ out.write(buf)
+ unpack(archive, location, log = log)
+ os.remove(archive)
+
+ possible = os.path.join(location, 'mingw64')
+ if not os.path.exists(possible):
+ possible = os.path.join(location, 'mingw32')
+ if not os.path.exists(possible):
+ raise ValueError('Failed to find unpacked MinGW: ' + possible)
+ return possible
+
+def root(location = None, arch = None, version = None, threading = None,
+ exceptions = None, revision = None, log = EmptyLogger()):
+ '''
+ Returns the root folder of a specific version of the mingw-builds variant
+ of gcc. Will download the compiler if needed
+ '''
+
+ # Get the repository if we don't have all the information
+ if not (arch and version and threading and exceptions and revision):
+ versions = repository(log = log)
+
+ # Determine some defaults
+ version = version or max(versions.keys())
+ if not arch:
+ arch = platform.machine().lower()
+ if arch == 'x86':
+ arch = 'i686'
+ elif arch == 'amd64':
+ arch = 'x86_64'
+ if not threading:
+ keys = versions[version][arch].keys()
+ if 'posix' in keys:
+ threading = 'posix'
+ elif 'win32' in keys:
+ threading = 'win32'
+ else:
+ threading = keys[0]
+ if not exceptions:
+ keys = versions[version][arch][threading].keys()
+ if 'seh' in keys:
+ exceptions = 'seh'
+ elif 'sjlj' in keys:
+ exceptions = 'sjlj'
+ else:
+ exceptions = keys[0]
+ if revision == None:
+ revision = max(versions[version][arch][threading][exceptions].keys())
+ if not location:
+ location = os.path.join(tempfile.gettempdir(), 'mingw-builds')
+
+ # Get the download url
+ url = versions[version][arch][threading][exceptions][revision]
+
+ # Tell the user whatzzup
+ log.info('finding MinGW %s', '.'.join(str(v) for v in version))
+ log.debug(' - arch: %s', arch)
+ log.debug(' - threading: %s', threading)
+ log.debug(' - exceptions: %s', exceptions)
+ log.debug(' - revision: %s', revision)
+ log.debug(' - url: %s', url)
+
+ # Store each specific revision differently
+ slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}'
+ slug = slug.format(
+ version = '.'.join(str(v) for v in version),
+ arch = arch,
+ threading = threading,
+ exceptions = exceptions,
+ revision = revision
+ )
+ if arch == 'x86_64':
+ root_dir = os.path.join(location, slug, 'mingw64')
+ elif arch == 'i686':
+ root_dir = os.path.join(location, slug, 'mingw32')
+ else:
+ raise ValueError('Unknown MinGW arch: ' + arch)
+
+ # Download if needed
+ if not os.path.exists(root_dir):
+ downloaded = download(url, os.path.join(location, slug), log = log)
+ if downloaded != root_dir:
+ raise ValueError('The location of mingw did not match\n%s\n%s'
+ % (downloaded, root_dir))
+
+ return root_dir
+
+def str2ver(string):
+ '''
+ Converts a version string into a tuple
+ '''
+ try:
+ version = tuple(int(v) for v in string.split('.'))
+ if len(version) is not 3:
+ raise ValueError()
+ except ValueError:
+ raise argparse.ArgumentTypeError(
+ 'please provide a three digit version string')
+ return version
+
+def main():
+ '''
+ Invoked when the script is run directly by the python interpreter
+ '''
+ parser = argparse.ArgumentParser(
+ description = 'Downloads a specific version of MinGW',
+ formatter_class = argparse.ArgumentDefaultsHelpFormatter
+ )
+ parser.add_argument('--location',
+ help = 'the location to download the compiler to',
+ default = os.path.join(tempfile.gettempdir(), 'mingw-builds'))
+ parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'],
+ help = 'the target MinGW architecture string')
+ parser.add_argument('--version', type = str2ver,
+ help = 'the version of GCC to download')
+ parser.add_argument('--threading', choices = ['posix', 'win32'],
+ help = 'the threading type of the compiler')
+ parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'],
+ help = 'the method to throw exceptions')
+ parser.add_argument('--revision', type=int,
+ help = 'the revision of the MinGW release')
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument('-v', '--verbose', action='store_true',
+ help='increase the script output verbosity')
+ group.add_argument('-q', '--quiet', action='store_true',
+ help='only print errors and warning')
+ args = parser.parse_args()
+
+ # Create the logger
+ logger = logging.getLogger('mingw')
+ handler = logging.StreamHandler()
+ formatter = logging.Formatter('%(message)s')
+ handler.setFormatter(formatter)
+ logger.addHandler(handler)
+ logger.setLevel(logging.INFO)
+ if args.quiet:
+ logger.setLevel(logging.WARN)
+ if args.verbose:
+ logger.setLevel(logging.DEBUG)
+
+ # Get MinGW
+ root_dir = root(location = args.location, arch = args.arch,
+ version = args.version, threading = args.threading,
+ exceptions = args.exceptions, revision = args.revision,
+ log = logger)
+
+ sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin'))
+
+if __name__ == '__main__':
+ try:
+ main()
+ except IOError as e:
+ sys.stderr.write('IO error: %s\n' % e)
+ sys.exit(1)
+ except OSError as e:
+ sys.stderr.write('OS error: %s\n' % e)
+ sys.exit(1)
+ except KeyboardInterrupt as e:
+ sys.stderr.write('Killed\n')
+ sys.exit(1)
diff --git a/utils/google-benchmark/src/benchmark.cc b/utils/google-benchmark/src/benchmark.cc
index b14bc629143e..aab07500af42 100644
--- a/utils/google-benchmark/src/benchmark.cc
+++ b/utils/google-benchmark/src/benchmark.cc
@@ -14,6 +14,7 @@
#include "benchmark/benchmark.h"
#include "benchmark_api_internal.h"
+#include "benchmark_runner.h"
#include "internal_macros.h"
#ifndef BENCHMARK_OS_WINDOWS
@@ -34,6 +35,7 @@
#include <memory>
#include <string>
#include <thread>
+#include <utility>
#include "check.h"
#include "colorprint.h"
@@ -55,9 +57,9 @@ DEFINE_bool(benchmark_list_tests, false,
DEFINE_string(benchmark_filter, ".",
"A regular expression that specifies the set of benchmarks "
- "to execute. If this flag is empty, no benchmarks are run. "
- "If this flag is the string \"all\", all benchmarks linked "
- "into the process are run.");
+ "to execute. If this flag is empty, or if this flag is the "
+ "string \"all\", all benchmarks linked into the binary are "
+ "run.");
DEFINE_double(benchmark_min_time, 0.5,
"Minimum number of seconds we should run benchmark before "
@@ -72,10 +74,19 @@ DEFINE_int32(benchmark_repetitions, 1,
"The number of runs of each benchmark. If greater than 1, the "
"mean and standard deviation of the runs will be reported.");
-DEFINE_bool(benchmark_report_aggregates_only, false,
- "Report the result of each benchmark repetitions. When 'true' is "
- "specified only the mean, standard deviation, and other statistics "
- "are reported for repeated benchmarks.");
+DEFINE_bool(
+ benchmark_report_aggregates_only, false,
+ "Report the result of each benchmark repetitions. When 'true' is specified "
+ "only the mean, standard deviation, and other statistics are reported for "
+ "repeated benchmarks. Affects all reporters.");
+
+DEFINE_bool(
+ benchmark_display_aggregates_only, false,
+ "Display the result of each benchmark repetitions. When 'true' is "
+ "specified only the mean, standard deviation, and other statistics are "
+ "displayed for repeated benchmarks. Unlike "
+ "benchmark_report_aggregates_only, only affects the display reporter, but "
+ "*NOT* file reporter, which will still contain all the output.");
DEFINE_string(benchmark_format, "console",
"The format to use for console output. Valid values are "
@@ -103,193 +114,11 @@ DEFINE_int32(v, 0, "The level of verbose logging to output");
namespace benchmark {
-namespace {
-static const size_t kMaxIterations = 1000000000;
-} // end namespace
-
namespace internal {
+// FIXME: wouldn't LTO mess this up?
void UseCharPointer(char const volatile*) {}
-namespace {
-
-BenchmarkReporter::Run CreateRunReport(
- const benchmark::internal::Benchmark::Instance& b,
- const internal::ThreadManager::Result& results, double seconds) {
- // Create report about this benchmark run.
- BenchmarkReporter::Run report;
-
- report.benchmark_name = b.name;
- report.error_occurred = results.has_error_;
- report.error_message = results.error_message_;
- report.report_label = results.report_label_;
- // This is the total iterations across all threads.
- report.iterations = results.iterations;
- report.time_unit = b.time_unit;
-
- if (!report.error_occurred) {
- double bytes_per_second = 0;
- if (results.bytes_processed > 0 && seconds > 0.0) {
- bytes_per_second = (results.bytes_processed / seconds);
- }
- double items_per_second = 0;
- if (results.items_processed > 0 && seconds > 0.0) {
- items_per_second = (results.items_processed / seconds);
- }
-
- if (b.use_manual_time) {
- report.real_accumulated_time = results.manual_time_used;
- } else {
- report.real_accumulated_time = results.real_time_used;
- }
- report.cpu_accumulated_time = results.cpu_time_used;
- report.bytes_per_second = bytes_per_second;
- report.items_per_second = items_per_second;
- report.complexity_n = results.complexity_n;
- report.complexity = b.complexity;
- report.complexity_lambda = b.complexity_lambda;
- report.statistics = b.statistics;
- report.counters = results.counters;
- internal::Finish(&report.counters, results.iterations, seconds, b.threads);
- }
- return report;
-}
-
-// Execute one thread of benchmark b for the specified number of iterations.
-// Adds the stats collected for the thread into *total.
-void RunInThread(const benchmark::internal::Benchmark::Instance* b,
- size_t iters, int thread_id,
- internal::ThreadManager* manager) {
- internal::ThreadTimer timer;
- State st(iters, b->arg, thread_id, b->threads, &timer, manager);
- b->benchmark->Run(st);
- CHECK(st.iterations() >= st.max_iterations)
- << "Benchmark returned before State::KeepRunning() returned false!";
- {
- MutexLock l(manager->GetBenchmarkMutex());
- internal::ThreadManager::Result& results = manager->results;
- results.iterations += st.iterations();
- results.cpu_time_used += timer.cpu_time_used();
- results.real_time_used += timer.real_time_used();
- results.manual_time_used += timer.manual_time_used();
- results.bytes_processed += st.bytes_processed();
- results.items_processed += st.items_processed();
- results.complexity_n += st.complexity_length_n();
- internal::Increment(&results.counters, st.counters);
- }
- manager->NotifyThreadComplete();
-}
-
-std::vector<BenchmarkReporter::Run> RunBenchmark(
- const benchmark::internal::Benchmark::Instance& b,
- std::vector<BenchmarkReporter::Run>* complexity_reports) {
- std::vector<BenchmarkReporter::Run> reports; // return value
-
- const bool has_explicit_iteration_count = b.iterations != 0;
- size_t iters = has_explicit_iteration_count ? b.iterations : 1;
- std::unique_ptr<internal::ThreadManager> manager;
- std::vector<std::thread> pool(b.threads - 1);
- const int repeats =
- b.repetitions != 0 ? b.repetitions : FLAGS_benchmark_repetitions;
- const bool report_aggregates_only =
- repeats != 1 &&
- (b.report_mode == internal::RM_Unspecified
- ? FLAGS_benchmark_report_aggregates_only
- : b.report_mode == internal::RM_ReportAggregatesOnly);
- for (int repetition_num = 0; repetition_num < repeats; repetition_num++) {
- for (;;) {
- // Try benchmark
- VLOG(2) << "Running " << b.name << " for " << iters << "\n";
-
- manager.reset(new internal::ThreadManager(b.threads));
- for (std::size_t ti = 0; ti < pool.size(); ++ti) {
- pool[ti] = std::thread(&RunInThread, &b, iters,
- static_cast<int>(ti + 1), manager.get());
- }
- RunInThread(&b, iters, 0, manager.get());
- manager->WaitForAllThreads();
- for (std::thread& thread : pool) thread.join();
- internal::ThreadManager::Result results;
- {
- MutexLock l(manager->GetBenchmarkMutex());
- results = manager->results;
- }
- manager.reset();
- // Adjust real/manual time stats since they were reported per thread.
- results.real_time_used /= b.threads;
- results.manual_time_used /= b.threads;
-
- VLOG(2) << "Ran in " << results.cpu_time_used << "/"
- << results.real_time_used << "\n";
-
- // Base decisions off of real time if requested by this benchmark.
- double seconds = results.cpu_time_used;
- if (b.use_manual_time) {
- seconds = results.manual_time_used;
- } else if (b.use_real_time) {
- seconds = results.real_time_used;
- }
-
- const double min_time =
- !IsZero(b.min_time) ? b.min_time : FLAGS_benchmark_min_time;
-
- // clang-format off
- // turn off clang-format since it mangles prettiness here
- // Determine if this run should be reported; Either it has
- // run for a sufficient amount of time or because an error was reported.
- const bool should_report = repetition_num > 0
- || has_explicit_iteration_count // An exact iteration count was requested
- || results.has_error_
- || iters >= kMaxIterations // No chance to try again, we hit the limit.
- || seconds >= min_time // the elapsed time is large enough
- // CPU time is specified but the elapsed real time greatly exceeds the
- // minimum time. Note that user provided timers are except from this
- // sanity check.
- || ((results.real_time_used >= 5 * min_time) && !b.use_manual_time);
- // clang-format on
-
- if (should_report) {
- BenchmarkReporter::Run report = CreateRunReport(b, results, seconds);
- if (!report.error_occurred && b.complexity != oNone)
- complexity_reports->push_back(report);
- reports.push_back(report);
- break;
- }
-
- // See how much iterations should be increased by
- // Note: Avoid division by zero with max(seconds, 1ns).
- double multiplier = min_time * 1.4 / std::max(seconds, 1e-9);
- // If our last run was at least 10% of FLAGS_benchmark_min_time then we
- // use the multiplier directly. Otherwise we use at most 10 times
- // expansion.
- // NOTE: When the last run was at least 10% of the min time the max
- // expansion should be 14x.
- bool is_significant = (seconds / min_time) > 0.1;
- multiplier = is_significant ? multiplier : std::min(10.0, multiplier);
- if (multiplier <= 1.0) multiplier = 2.0;
- double next_iters = std::max(multiplier * iters, iters + 1.0);
- if (next_iters > kMaxIterations) {
- next_iters = kMaxIterations;
- }
- VLOG(3) << "Next iters: " << next_iters << ", " << multiplier << "\n";
- iters = static_cast<int>(next_iters + 0.5);
- }
- }
- // Calculate additional statistics
- auto stat_reports = ComputeStats(reports);
- if ((b.complexity != oNone) && b.last_benchmark_instance) {
- auto additional_run_stats = ComputeBigO(*complexity_reports);
- stat_reports.insert(stat_reports.end(), additional_run_stats.begin(),
- additional_run_stats.end());
- complexity_reports->clear();
- }
-
- if (report_aggregates_only) reports.clear();
- reports.insert(reports.end(), stat_reports.begin(), stat_reports.end());
- return reports;
-}
-
-} // namespace
} // namespace internal
State::State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
@@ -302,8 +131,6 @@ State::State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
finished_(false),
error_occurred_(false),
range_(ranges),
- bytes_processed_(0),
- items_processed_(0),
complexity_n_(0),
counters(),
thread_index(thread_i),
@@ -394,25 +221,25 @@ void State::FinishKeepRunning() {
namespace internal {
namespace {
-void RunBenchmarks(const std::vector<Benchmark::Instance>& benchmarks,
- BenchmarkReporter* console_reporter,
+void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
+ BenchmarkReporter* display_reporter,
BenchmarkReporter* file_reporter) {
// Note the file_reporter can be null.
- CHECK(console_reporter != nullptr);
+ CHECK(display_reporter != nullptr);
// Determine the width of the name field using a minimum width of 10.
- bool has_repetitions = FLAGS_benchmark_repetitions > 1;
+ bool might_have_aggregates = FLAGS_benchmark_repetitions > 1;
size_t name_field_width = 10;
size_t stat_field_width = 0;
- for (const Benchmark::Instance& benchmark : benchmarks) {
+ for (const BenchmarkInstance& benchmark : benchmarks) {
name_field_width =
std::max<size_t>(name_field_width, benchmark.name.size());
- has_repetitions |= benchmark.repetitions > 1;
+ might_have_aggregates |= benchmark.repetitions > 1;
for (const auto& Stat : *benchmark.statistics)
stat_field_width = std::max<size_t>(stat_field_width, Stat.name_.size());
}
- if (has_repetitions) name_field_width += 1 + stat_field_width;
+ if (might_have_aggregates) name_field_width += 1 + stat_field_width;
// Print header here
BenchmarkReporter::Context context;
@@ -429,22 +256,36 @@ void RunBenchmarks(const std::vector<Benchmark::Instance>& benchmarks,
std::flush(reporter->GetErrorStream());
};
- if (console_reporter->ReportContext(context) &&
+ if (display_reporter->ReportContext(context) &&
(!file_reporter || file_reporter->ReportContext(context))) {
- flushStreams(console_reporter);
+ flushStreams(display_reporter);
flushStreams(file_reporter);
+
for (const auto& benchmark : benchmarks) {
- std::vector<BenchmarkReporter::Run> reports =
- RunBenchmark(benchmark, &complexity_reports);
- console_reporter->ReportRuns(reports);
- if (file_reporter) file_reporter->ReportRuns(reports);
- flushStreams(console_reporter);
+ RunResults run_results = RunBenchmark(benchmark, &complexity_reports);
+
+ auto report = [&run_results](BenchmarkReporter* reporter,
+ bool report_aggregates_only) {
+ assert(reporter);
+ // If there are no aggregates, do output non-aggregates.
+ report_aggregates_only &= !run_results.aggregates_only.empty();
+ if (!report_aggregates_only)
+ reporter->ReportRuns(run_results.non_aggregates);
+ if (!run_results.aggregates_only.empty())
+ reporter->ReportRuns(run_results.aggregates_only);
+ };
+
+ report(display_reporter, run_results.display_report_aggregates_only);
+ if (file_reporter)
+ report(file_reporter, run_results.file_report_aggregates_only);
+
+ flushStreams(display_reporter);
flushStreams(file_reporter);
}
}
- console_reporter->Finalize();
+ display_reporter->Finalize();
if (file_reporter) file_reporter->Finalize();
- flushStreams(console_reporter);
+ flushStreams(display_reporter);
flushStreams(file_reporter);
}
@@ -471,15 +312,20 @@ bool IsZero(double n) {
ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
int output_opts = ConsoleReporter::OO_Defaults;
- if ((FLAGS_benchmark_color == "auto" && IsColorTerminal()) ||
- IsTruthyFlagValue(FLAGS_benchmark_color)) {
+ auto is_benchmark_color = [force_no_color] () -> bool {
+ if (force_no_color) {
+ return false;
+ }
+ if (FLAGS_benchmark_color == "auto") {
+ return IsColorTerminal();
+ }
+ return IsTruthyFlagValue(FLAGS_benchmark_color);
+ };
+ if (is_benchmark_color()) {
output_opts |= ConsoleReporter::OO_Color;
} else {
output_opts &= ~ConsoleReporter::OO_Color;
}
- if (force_no_color) {
- output_opts &= ~ConsoleReporter::OO_Color;
- }
if (FLAGS_benchmark_counters_tabular) {
output_opts |= ConsoleReporter::OO_Tabular;
} else {
@@ -494,11 +340,11 @@ size_t RunSpecifiedBenchmarks() {
return RunSpecifiedBenchmarks(nullptr, nullptr);
}
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter) {
- return RunSpecifiedBenchmarks(console_reporter, nullptr);
+size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) {
+ return RunSpecifiedBenchmarks(display_reporter, nullptr);
}
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
+size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
BenchmarkReporter* file_reporter) {
std::string spec = FLAGS_benchmark_filter;
if (spec.empty() || spec == "all")
@@ -506,15 +352,15 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
// Setup the reporters
std::ofstream output_file;
- std::unique_ptr<BenchmarkReporter> default_console_reporter;
+ std::unique_ptr<BenchmarkReporter> default_display_reporter;
std::unique_ptr<BenchmarkReporter> default_file_reporter;
- if (!console_reporter) {
- default_console_reporter = internal::CreateReporter(
+ if (!display_reporter) {
+ default_display_reporter = internal::CreateReporter(
FLAGS_benchmark_format, internal::GetOutputOptions());
- console_reporter = default_console_reporter.get();
+ display_reporter = default_display_reporter.get();
}
- auto& Out = console_reporter->GetOutputStream();
- auto& Err = console_reporter->GetErrorStream();
+ auto& Out = display_reporter->GetOutputStream();
+ auto& Err = display_reporter->GetErrorStream();
std::string const& fname = FLAGS_benchmark_out;
if (fname.empty() && file_reporter) {
@@ -538,7 +384,7 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
file_reporter->SetErrorStream(&output_file);
}
- std::vector<internal::Benchmark::Instance> benchmarks;
+ std::vector<internal::BenchmarkInstance> benchmarks;
if (!FindBenchmarksInternal(spec, &benchmarks, &Err)) return 0;
if (benchmarks.empty()) {
@@ -549,12 +395,16 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
if (FLAGS_benchmark_list_tests) {
for (auto const& benchmark : benchmarks) Out << benchmark.name << "\n";
} else {
- internal::RunBenchmarks(benchmarks, console_reporter, file_reporter);
+ internal::RunBenchmarks(benchmarks, display_reporter, file_reporter);
}
return benchmarks.size();
}
+void RegisterMemoryManager(MemoryManager* manager) {
+ internal::memory_manager = manager;
+}
+
namespace internal {
void PrintUsageAndExit() {
@@ -564,7 +414,8 @@ void PrintUsageAndExit() {
" [--benchmark_filter=<regex>]\n"
" [--benchmark_min_time=<min_time>]\n"
" [--benchmark_repetitions=<num_repetitions>]\n"
- " [--benchmark_report_aggregates_only={true|false}\n"
+ " [--benchmark_report_aggregates_only={true|false}]\n"
+ " [--benchmark_display_aggregates_only={true|false}]\n"
" [--benchmark_format=<console|json|csv>]\n"
" [--benchmark_out=<filename>]\n"
" [--benchmark_out_format=<json|console|csv>]\n"
@@ -588,6 +439,8 @@ void ParseCommandLineFlags(int* argc, char** argv) {
&FLAGS_benchmark_repetitions) ||
ParseBoolFlag(argv[i], "benchmark_report_aggregates_only",
&FLAGS_benchmark_report_aggregates_only) ||
+ ParseBoolFlag(argv[i], "benchmark_display_aggregates_only",
+ &FLAGS_benchmark_display_aggregates_only) ||
ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) ||
ParseStringFlag(argv[i], "benchmark_out", &FLAGS_benchmark_out) ||
ParseStringFlag(argv[i], "benchmark_out_format",
diff --git a/utils/google-benchmark/src/benchmark_api_internal.cc b/utils/google-benchmark/src/benchmark_api_internal.cc
new file mode 100644
index 000000000000..8d3108363b8c
--- /dev/null
+++ b/utils/google-benchmark/src/benchmark_api_internal.cc
@@ -0,0 +1,15 @@
+#include "benchmark_api_internal.h"
+
+namespace benchmark {
+namespace internal {
+
+State BenchmarkInstance::Run(
+ size_t iters, int thread_id, internal::ThreadTimer* timer,
+ internal::ThreadManager* manager) const {
+ State st(iters, arg, thread_id, threads, timer, manager);
+ benchmark->Run(st);
+ return st;
+}
+
+} // internal
+} // benchmark
diff --git a/utils/google-benchmark/src/benchmark_api_internal.h b/utils/google-benchmark/src/benchmark_api_internal.h
index dd7a3ffe8cbb..0524a85c01d0 100644
--- a/utils/google-benchmark/src/benchmark_api_internal.h
+++ b/utils/google-benchmark/src/benchmark_api_internal.h
@@ -2,10 +2,12 @@
#define BENCHMARK_API_INTERNAL_H
#include "benchmark/benchmark.h"
+#include "commandlineflags.h"
#include <cmath>
#include <iosfwd>
#include <limits>
+#include <memory>
#include <string>
#include <vector>
@@ -13,10 +15,10 @@ namespace benchmark {
namespace internal {
// Information kept per benchmark we may want to run
-struct Benchmark::Instance {
+struct BenchmarkInstance {
std::string name;
Benchmark* benchmark;
- ReportMode report_mode;
+ AggregationReportMode aggregation_report_mode;
std::vector<int64_t> arg;
TimeUnit time_unit;
int range_multiplier;
@@ -31,10 +33,13 @@ struct Benchmark::Instance {
double min_time;
size_t iterations;
int threads; // Number of concurrent threads to us
+
+ State Run(size_t iters, int thread_id, internal::ThreadTimer* timer,
+ internal::ThreadManager* manager) const;
};
bool FindBenchmarksInternal(const std::string& re,
- std::vector<Benchmark::Instance>* benchmarks,
+ std::vector<BenchmarkInstance>* benchmarks,
std::ostream* Err);
bool IsZero(double n);
diff --git a/utils/google-benchmark/src/benchmark_register.cc b/utils/google-benchmark/src/benchmark_register.cc
index 26a89721c786..f17f5b223cec 100644
--- a/utils/google-benchmark/src/benchmark_register.cc
+++ b/utils/google-benchmark/src/benchmark_register.cc
@@ -78,7 +78,7 @@ class BenchmarkFamilies {
// Extract the list of benchmark instances that match the specified
// regular expression.
bool FindBenchmarks(std::string re,
- std::vector<Benchmark::Instance>* benchmarks,
+ std::vector<BenchmarkInstance>* benchmarks,
std::ostream* Err);
private:
@@ -107,7 +107,7 @@ void BenchmarkFamilies::ClearBenchmarks() {
}
bool BenchmarkFamilies::FindBenchmarks(
- std::string spec, std::vector<Benchmark::Instance>* benchmarks,
+ std::string spec, std::vector<BenchmarkInstance>* benchmarks,
std::ostream* ErrStream) {
CHECK(ErrStream);
auto& Err = *ErrStream;
@@ -152,10 +152,10 @@ bool BenchmarkFamilies::FindBenchmarks(
for (auto const& args : family->args_) {
for (int num_threads : *thread_counts) {
- Benchmark::Instance instance;
+ BenchmarkInstance instance;
instance.name = family->name_;
instance.benchmark = family.get();
- instance.report_mode = family->report_mode_;
+ instance.aggregation_report_mode = family->aggregation_report_mode_;
instance.arg = args;
instance.time_unit = family->time_unit_;
instance.range_multiplier = family->range_multiplier_;
@@ -182,14 +182,19 @@ bool BenchmarkFamilies::FindBenchmarks(
}
}
- instance.name += StrFormat("%d", arg);
+ // we know that the args are always non-negative (see 'AddRange()'),
+ // thus print as 'unsigned'. BUT, do a cast due to the 32-bit builds.
+ instance.name += StrFormat("%lu", static_cast<unsigned long>(arg));
++arg_i;
}
if (!IsZero(family->min_time_))
instance.name += StrFormat("/min_time:%0.3f", family->min_time_);
- if (family->iterations_ != 0)
- instance.name += StrFormat("/iterations:%d", family->iterations_);
+ if (family->iterations_ != 0) {
+ instance.name +=
+ StrFormat("/iterations:%lu",
+ static_cast<unsigned long>(family->iterations_));
+ }
if (family->repetitions_ != 0)
instance.name += StrFormat("/repeats:%d", family->repetitions_);
@@ -225,7 +230,7 @@ Benchmark* RegisterBenchmarkInternal(Benchmark* bench) {
// FIXME: This function is a hack so that benchmark.cc can access
// `BenchmarkFamilies`
bool FindBenchmarksInternal(const std::string& re,
- std::vector<Benchmark::Instance>* benchmarks,
+ std::vector<BenchmarkInstance>* benchmarks,
std::ostream* Err) {
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
}
@@ -236,7 +241,7 @@ bool FindBenchmarksInternal(const std::string& re,
Benchmark::Benchmark(const char* name)
: name_(name),
- report_mode_(RM_Unspecified),
+ aggregation_report_mode_(ARM_Unspecified),
time_unit_(kNanosecond),
range_multiplier_(kRangeMultiplier),
min_time_(0),
@@ -369,7 +374,23 @@ Benchmark* Benchmark::Repetitions(int n) {
}
Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
- report_mode_ = value ? RM_ReportAggregatesOnly : RM_Default;
+ aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
+ return this;
+}
+
+Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
+ // If we were called, the report mode is no longer 'unspecified', in any case.
+ aggregation_report_mode_ = static_cast<AggregationReportMode>(
+ aggregation_report_mode_ | ARM_Default);
+
+ if (value) {
+ aggregation_report_mode_ = static_cast<AggregationReportMode>(
+ aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
+ } else {
+ aggregation_report_mode_ = static_cast<AggregationReportMode>(
+ aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
+ }
+
return this;
}
diff --git a/utils/google-benchmark/src/benchmark_runner.cc b/utils/google-benchmark/src/benchmark_runner.cc
new file mode 100644
index 000000000000..38faeec8e3ee
--- /dev/null
+++ b/utils/google-benchmark/src/benchmark_runner.cc
@@ -0,0 +1,350 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "benchmark_runner.h"
+#include "benchmark/benchmark.h"
+#include "benchmark_api_internal.h"
+#include "internal_macros.h"
+
+#ifndef BENCHMARK_OS_WINDOWS
+#ifndef BENCHMARK_OS_FUCHSIA
+#include <sys/resource.h>
+#endif
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+
+#include "check.h"
+#include "colorprint.h"
+#include "commandlineflags.h"
+#include "complexity.h"
+#include "counter.h"
+#include "internal_macros.h"
+#include "log.h"
+#include "mutex.h"
+#include "re.h"
+#include "statistics.h"
+#include "string_util.h"
+#include "thread_manager.h"
+#include "thread_timer.h"
+
+namespace benchmark {
+
+namespace internal {
+
+MemoryManager* memory_manager = nullptr;
+
+namespace {
+
+static const size_t kMaxIterations = 1000000000;
+
+BenchmarkReporter::Run CreateRunReport(
+ const benchmark::internal::BenchmarkInstance& b,
+ const internal::ThreadManager::Result& results, size_t memory_iterations,
+ const MemoryManager::Result& memory_result, double seconds) {
+ // Create report about this benchmark run.
+ BenchmarkReporter::Run report;
+
+ report.run_name = b.name;
+ report.error_occurred = results.has_error_;
+ report.error_message = results.error_message_;
+ report.report_label = results.report_label_;
+ // This is the total iterations across all threads.
+ report.iterations = results.iterations;
+ report.time_unit = b.time_unit;
+
+ if (!report.error_occurred) {
+ if (b.use_manual_time) {
+ report.real_accumulated_time = results.manual_time_used;
+ } else {
+ report.real_accumulated_time = results.real_time_used;
+ }
+ report.cpu_accumulated_time = results.cpu_time_used;
+ report.complexity_n = results.complexity_n;
+ report.complexity = b.complexity;
+ report.complexity_lambda = b.complexity_lambda;
+ report.statistics = b.statistics;
+ report.counters = results.counters;
+
+ if (memory_iterations > 0) {
+ report.has_memory_result = true;
+ report.allocs_per_iter =
+ memory_iterations ? static_cast<double>(memory_result.num_allocs) /
+ memory_iterations
+ : 0;
+ report.max_bytes_used = memory_result.max_bytes_used;
+ }
+
+ internal::Finish(&report.counters, results.iterations, seconds, b.threads);
+ }
+ return report;
+}
+
+// Execute one thread of benchmark b for the specified number of iterations.
+// Adds the stats collected for the thread into *total.
+void RunInThread(const BenchmarkInstance* b, size_t iters, int thread_id,
+ ThreadManager* manager) {
+ internal::ThreadTimer timer;
+ State st = b->Run(iters, thread_id, &timer, manager);
+ CHECK(st.iterations() >= st.max_iterations)
+ << "Benchmark returned before State::KeepRunning() returned false!";
+ {
+ MutexLock l(manager->GetBenchmarkMutex());
+ internal::ThreadManager::Result& results = manager->results;
+ results.iterations += st.iterations();
+ results.cpu_time_used += timer.cpu_time_used();
+ results.real_time_used += timer.real_time_used();
+ results.manual_time_used += timer.manual_time_used();
+ results.complexity_n += st.complexity_length_n();
+ internal::Increment(&results.counters, st.counters);
+ }
+ manager->NotifyThreadComplete();
+}
+
+class BenchmarkRunner {
+ public:
+ BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_,
+ std::vector<BenchmarkReporter::Run>* complexity_reports_)
+ : b(b_),
+ complexity_reports(*complexity_reports_),
+ min_time(!IsZero(b.min_time) ? b.min_time : FLAGS_benchmark_min_time),
+ repeats(b.repetitions != 0 ? b.repetitions
+ : FLAGS_benchmark_repetitions),
+ has_explicit_iteration_count(b.iterations != 0),
+ pool(b.threads - 1),
+ iters(has_explicit_iteration_count ? b.iterations : 1) {
+ run_results.display_report_aggregates_only =
+ (FLAGS_benchmark_report_aggregates_only ||
+ FLAGS_benchmark_display_aggregates_only);
+ run_results.file_report_aggregates_only =
+ FLAGS_benchmark_report_aggregates_only;
+ if (b.aggregation_report_mode != internal::ARM_Unspecified) {
+ run_results.display_report_aggregates_only =
+ (b.aggregation_report_mode &
+ internal::ARM_DisplayReportAggregatesOnly);
+ run_results.file_report_aggregates_only =
+ (b.aggregation_report_mode & internal::ARM_FileReportAggregatesOnly);
+ }
+
+ for (int repetition_num = 0; repetition_num < repeats; repetition_num++) {
+ const bool is_the_first_repetition = repetition_num == 0;
+ DoOneRepetition(is_the_first_repetition);
+ }
+
+ // Calculate additional statistics
+ run_results.aggregates_only = ComputeStats(run_results.non_aggregates);
+
+ // Maybe calculate complexity report
+ if ((b.complexity != oNone) && b.last_benchmark_instance) {
+ auto additional_run_stats = ComputeBigO(complexity_reports);
+ run_results.aggregates_only.insert(run_results.aggregates_only.end(),
+ additional_run_stats.begin(),
+ additional_run_stats.end());
+ complexity_reports.clear();
+ }
+ }
+
+ RunResults&& get_results() { return std::move(run_results); }
+
+ private:
+ RunResults run_results;
+
+ const benchmark::internal::BenchmarkInstance& b;
+ std::vector<BenchmarkReporter::Run>& complexity_reports;
+
+ const double min_time;
+ const int repeats;
+ const bool has_explicit_iteration_count;
+
+ std::vector<std::thread> pool;
+
+ size_t iters; // preserved between repetitions!
+ // So only the first repetition has to find/calculate it,
+ // the other repetitions will just use that precomputed iteration count.
+
+ struct IterationResults {
+ internal::ThreadManager::Result results;
+ size_t iters;
+ double seconds;
+ };
+ IterationResults DoNIterations() {
+ VLOG(2) << "Running " << b.name << " for " << iters << "\n";
+
+ std::unique_ptr<internal::ThreadManager> manager;
+ manager.reset(new internal::ThreadManager(b.threads));
+
+ // Run all but one thread in separate threads
+ for (std::size_t ti = 0; ti < pool.size(); ++ti) {
+ pool[ti] = std::thread(&RunInThread, &b, iters, static_cast<int>(ti + 1),
+ manager.get());
+ }
+ // And run one thread here directly.
+ // (If we were asked to run just one thread, we don't create new threads.)
+ // Yes, we need to do this here *after* we start the separate threads.
+ RunInThread(&b, iters, 0, manager.get());
+
+ // The main thread has finished. Now let's wait for the other threads.
+ manager->WaitForAllThreads();
+ for (std::thread& thread : pool) thread.join();
+
+ IterationResults i;
+ // Acquire the measurements/counters from the manager, UNDER THE LOCK!
+ {
+ MutexLock l(manager->GetBenchmarkMutex());
+ i.results = manager->results;
+ }
+
+ // And get rid of the manager.
+ manager.reset();
+
+ // Adjust real/manual time stats since they were reported per thread.
+ i.results.real_time_used /= b.threads;
+ i.results.manual_time_used /= b.threads;
+
+ VLOG(2) << "Ran in " << i.results.cpu_time_used << "/"
+ << i.results.real_time_used << "\n";
+
+ // So for how long were we running?
+ i.iters = iters;
+ // Base decisions off of real time if requested by this benchmark.
+ i.seconds = i.results.cpu_time_used;
+ if (b.use_manual_time) {
+ i.seconds = i.results.manual_time_used;
+ } else if (b.use_real_time) {
+ i.seconds = i.results.real_time_used;
+ }
+
+ return i;
+ }
+
+ size_t PredictNumItersNeeded(const IterationResults& i) const {
+ // See how much iterations should be increased by.
+ // Note: Avoid division by zero with max(seconds, 1ns).
+ double multiplier = min_time * 1.4 / std::max(i.seconds, 1e-9);
+ // If our last run was at least 10% of FLAGS_benchmark_min_time then we
+ // use the multiplier directly.
+ // Otherwise we use at most 10 times expansion.
+ // NOTE: When the last run was at least 10% of the min time the max
+ // expansion should be 14x.
+ bool is_significant = (i.seconds / min_time) > 0.1;
+ multiplier = is_significant ? multiplier : std::min(10.0, multiplier);
+ if (multiplier <= 1.0) multiplier = 2.0;
+
+ // So what seems to be the sufficiently-large iteration count? Round up.
+ const size_t max_next_iters =
+ 0.5 + std::max(multiplier * i.iters, i.iters + 1.0);
+ // But we do have *some* sanity limits though..
+ const size_t next_iters = std::min(max_next_iters, kMaxIterations);
+
+ VLOG(3) << "Next iters: " << next_iters << ", " << multiplier << "\n";
+ return next_iters; // round up before conversion to integer.
+ }
+
+ bool ShouldReportIterationResults(const IterationResults& i) const {
+ // Determine if this run should be reported;
+ // Either it has run for a sufficient amount of time
+ // or because an error was reported.
+ return i.results.has_error_ ||
+ i.iters >= kMaxIterations || // Too many iterations already.
+ i.seconds >= min_time || // The elapsed time is large enough.
+ // CPU time is specified but the elapsed real time greatly exceeds
+ // the minimum time.
+ // Note that user provided timers are except from this sanity check.
+ ((i.results.real_time_used >= 5 * min_time) && !b.use_manual_time);
+ }
+
+ void DoOneRepetition(bool is_the_first_repetition) {
+ IterationResults i;
+
+ // We *may* be gradually increasing the length (iteration count)
+ // of the benchmark until we decide the results are significant.
+ // And once we do, we report those last results and exit.
+ // Please do note that the if there are repetitions, the iteration count
+ // is *only* calculated for the *first* repetition, and other repetitions
+ // simply use that precomputed iteration count.
+ for (;;) {
+ i = DoNIterations();
+
+ // Do we consider the results to be significant?
+ // If we are doing repetitions, and the first repetition was already done,
+ // it has calculated the correct iteration time, so we have run that very
+ // iteration count just now. No need to calculate anything. Just report.
+ // Else, the normal rules apply.
+ const bool results_are_significant = !is_the_first_repetition ||
+ has_explicit_iteration_count ||
+ ShouldReportIterationResults(i);
+
+ if (results_are_significant) break; // Good, let's report them!
+
+ // Nope, bad iteration. Let's re-estimate the hopefully-sufficient
+ // iteration count, and run the benchmark again...
+
+ iters = PredictNumItersNeeded(i);
+ assert(iters > i.iters &&
+ "if we did more iterations than we want to do the next time, "
+ "then we should have accepted the current iteration run.");
+ }
+
+ // Oh, one last thing, we need to also produce the 'memory measurements'..
+ MemoryManager::Result memory_result;
+ size_t memory_iterations = 0;
+ if (memory_manager != nullptr) {
+ // Only run a few iterations to reduce the impact of one-time
+ // allocations in benchmarks that are not properly managed.
+ memory_iterations = std::min<size_t>(16, iters);
+ memory_manager->Start();
+ std::unique_ptr<internal::ThreadManager> manager;
+ manager.reset(new internal::ThreadManager(1));
+ RunInThread(&b, memory_iterations, 0, manager.get());
+ manager->WaitForAllThreads();
+ manager.reset();
+
+ memory_manager->Stop(&memory_result);
+ }
+
+ // Ok, now actualy report.
+ BenchmarkReporter::Run report = CreateRunReport(
+ b, i.results, memory_iterations, memory_result, i.seconds);
+
+ if (!report.error_occurred && b.complexity != oNone)
+ complexity_reports.push_back(report);
+
+ run_results.non_aggregates.push_back(report);
+ }
+};
+
+} // end namespace
+
+RunResults RunBenchmark(
+ const benchmark::internal::BenchmarkInstance& b,
+ std::vector<BenchmarkReporter::Run>* complexity_reports) {
+ internal::BenchmarkRunner r(b, complexity_reports);
+ return r.get_results();
+}
+
+} // end namespace internal
+
+} // end namespace benchmark
diff --git a/utils/google-benchmark/src/benchmark_runner.h b/utils/google-benchmark/src/benchmark_runner.h
new file mode 100644
index 000000000000..96e8282a11aa
--- /dev/null
+++ b/utils/google-benchmark/src/benchmark_runner.h
@@ -0,0 +1,51 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_RUNNER_H_
+#define BENCHMARK_RUNNER_H_
+
+#include "benchmark_api_internal.h"
+#include "internal_macros.h"
+
+DECLARE_double(benchmark_min_time);
+
+DECLARE_int32(benchmark_repetitions);
+
+DECLARE_bool(benchmark_report_aggregates_only);
+
+DECLARE_bool(benchmark_display_aggregates_only);
+
+namespace benchmark {
+
+namespace internal {
+
+extern MemoryManager* memory_manager;
+
+struct RunResults {
+ std::vector<BenchmarkReporter::Run> non_aggregates;
+ std::vector<BenchmarkReporter::Run> aggregates_only;
+
+ bool display_report_aggregates_only = false;
+ bool file_report_aggregates_only = false;
+};
+
+RunResults RunBenchmark(
+ const benchmark::internal::BenchmarkInstance& b,
+ std::vector<BenchmarkReporter::Run>* complexity_reports);
+
+} // namespace internal
+
+} // end namespace benchmark
+
+#endif // BENCHMARK_RUNNER_H_
diff --git a/utils/google-benchmark/src/colorprint.cc b/utils/google-benchmark/src/colorprint.cc
index 2dec4a8b28ba..fff6a98818b8 100644
--- a/utils/google-benchmark/src/colorprint.cc
+++ b/utils/google-benchmark/src/colorprint.cc
@@ -25,7 +25,7 @@
#include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS
-#include <Windows.h>
+#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
diff --git a/utils/google-benchmark/src/complexity.cc b/utils/google-benchmark/src/complexity.cc
index aafd538df215..6ef17660c954 100644
--- a/utils/google-benchmark/src/complexity.cc
+++ b/utils/google-benchmark/src/complexity.cc
@@ -73,8 +73,8 @@ std::string GetBigOString(BigO complexity) {
// - time : Vector containing the times for the benchmark tests.
// - fitting_curve : lambda expression (e.g. [](int64_t n) {return n; };).
-// For a deeper explanation on the algorithm logic, look the README file at
-// http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit
+// For a deeper explanation on the algorithm logic, please refer to
+// https://en.wikipedia.org/wiki/Least_squares#Least_squares,_regression_analysis_and_statistics
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
const std::vector<double>& time,
@@ -182,12 +182,15 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
result_cpu = MinimalLeastSq(n, cpu_time, reports[0].complexity);
result_real = MinimalLeastSq(n, real_time, result_cpu.complexity);
}
- std::string benchmark_name =
- reports[0].benchmark_name.substr(0, reports[0].benchmark_name.find('/'));
+
+ std::string run_name = reports[0].benchmark_name().substr(
+ 0, reports[0].benchmark_name().find('/'));
// Get the data from the accumulator to BenchmarkReporter::Run's.
Run big_o;
- big_o.benchmark_name = benchmark_name + "_BigO";
+ big_o.run_name = run_name;
+ big_o.run_type = BenchmarkReporter::Run::RT_Aggregate;
+ big_o.aggregate_name = "BigO";
big_o.iterations = 0;
big_o.real_accumulated_time = result_real.coef;
big_o.cpu_accumulated_time = result_cpu.coef;
@@ -203,8 +206,10 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
// Only add label to mean/stddev if it is same for all runs
Run rms;
+ rms.run_name = run_name;
big_o.report_label = reports[0].report_label;
- rms.benchmark_name = benchmark_name + "_RMS";
+ rms.run_type = BenchmarkReporter::Run::RT_Aggregate;
+ rms.aggregate_name = "RMS";
rms.report_label = big_o.report_label;
rms.iterations = 0;
rms.real_accumulated_time = result_real.rms / multiplier;
diff --git a/utils/google-benchmark/src/console_reporter.cc b/utils/google-benchmark/src/console_reporter.cc
index 48920ca78295..ca364727cb46 100644
--- a/utils/google-benchmark/src/console_reporter.cc
+++ b/utils/google-benchmark/src/console_reporter.cc
@@ -53,7 +53,7 @@ bool ConsoleReporter::ReportContext(const Context& context) {
}
void ConsoleReporter::PrintHeader(const Run& run) {
- std::string str = FormatString("%-*s %13s %13s %10s", static_cast<int>(name_field_width_),
+ std::string str = FormatString("%-*s %13s %15s %12s", static_cast<int>(name_field_width_),
"Benchmark", "Time", "CPU", "Iterations");
if(!run.counters.empty()) {
if(output_options_ & OO_Tabular) {
@@ -98,6 +98,21 @@ static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt,
va_end(args);
}
+
+static std::string FormatTime(double time) {
+ // Align decimal places...
+ if (time < 1.0) {
+ return FormatString("%10.3f", time);
+ }
+ if (time < 10.0) {
+ return FormatString("%10.2f", time);
+ }
+ if (time < 100.0) {
+ return FormatString("%10.1f", time);
+ }
+ return FormatString("%10.0f", time);
+}
+
void ConsoleReporter::PrintRunData(const Run& result) {
typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...);
auto& Out = GetOutputStream();
@@ -106,7 +121,7 @@ void ConsoleReporter::PrintRunData(const Run& result) {
auto name_color =
(result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN;
printer(Out, name_color, "%-*s ", name_field_width_,
- result.benchmark_name.c_str());
+ result.benchmark_name().c_str());
if (result.error_occurred) {
printer(Out, COLOR_RED, "ERROR OCCURRED: \'%s\'",
@@ -114,33 +129,24 @@ void ConsoleReporter::PrintRunData(const Run& result) {
printer(Out, COLOR_DEFAULT, "\n");
return;
}
- // Format bytes per second
- std::string rate;
- if (result.bytes_per_second > 0) {
- rate = StrCat(" ", HumanReadableNumber(result.bytes_per_second), "B/s");
- }
-
- // Format items per second
- std::string items;
- if (result.items_per_second > 0) {
- items =
- StrCat(" ", HumanReadableNumber(result.items_per_second), " items/s");
- }
const double real_time = result.GetAdjustedRealTime();
const double cpu_time = result.GetAdjustedCPUTime();
+ const std::string real_time_str = FormatTime(real_time);
+ const std::string cpu_time_str = FormatTime(cpu_time);
+
if (result.report_big_o) {
std::string big_o = GetBigOString(result.complexity);
- printer(Out, COLOR_YELLOW, "%10.2f %s %10.2f %s ", real_time, big_o.c_str(),
+ printer(Out, COLOR_YELLOW, "%10.2f %-4s %10.2f %-4s ", real_time, big_o.c_str(),
cpu_time, big_o.c_str());
} else if (result.report_rms) {
- printer(Out, COLOR_YELLOW, "%10.0f %% %10.0f %% ", real_time * 100,
- cpu_time * 100);
+ printer(Out, COLOR_YELLOW, "%10.0f %-4s %10.0f %-4s ", real_time * 100, "%",
+ cpu_time * 100, "%");
} else {
const char* timeLabel = GetTimeUnitString(result.time_unit);
- printer(Out, COLOR_YELLOW, "%10.0f %s %10.0f %s ", real_time, timeLabel,
- cpu_time, timeLabel);
+ printer(Out, COLOR_YELLOW, "%s %-4s %s %-4s ", real_time_str.c_str(), timeLabel,
+ cpu_time_str.c_str(), timeLabel);
}
if (!result.report_big_o && !result.report_rms) {
@@ -150,7 +156,7 @@ void ConsoleReporter::PrintRunData(const Run& result) {
for (auto& c : result.counters) {
const std::size_t cNameLen = std::max(std::string::size_type(10),
c.first.length());
- auto const& s = HumanReadableNumber(c.second.value, 1000);
+ auto const& s = HumanReadableNumber(c.second.value, c.second.oneK);
if (output_options_ & OO_Tabular) {
if (c.second.flags & Counter::kIsRate) {
printer(Out, COLOR_DEFAULT, " %*s/s", cNameLen - 2, s.c_str());
@@ -164,14 +170,6 @@ void ConsoleReporter::PrintRunData(const Run& result) {
}
}
- if (!rate.empty()) {
- printer(Out, COLOR_DEFAULT, " %*s", 13, rate.c_str());
- }
-
- if (!items.empty()) {
- printer(Out, COLOR_DEFAULT, " %*s", 18, items.c_str());
- }
-
if (!result.report_label.empty()) {
printer(Out, COLOR_DEFAULT, " %s", result.report_label.c_str());
}
diff --git a/utils/google-benchmark/src/csv_reporter.cc b/utils/google-benchmark/src/csv_reporter.cc
index 4a641909d808..d2f1d27eb62c 100644
--- a/utils/google-benchmark/src/csv_reporter.cc
+++ b/utils/google-benchmark/src/csv_reporter.cc
@@ -49,6 +49,8 @@ void CSVReporter::ReportRuns(const std::vector<Run>& reports) {
// save the names of all the user counters
for (const auto& run : reports) {
for (const auto& cnt : run.counters) {
+ if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second")
+ continue;
user_counter_names_.insert(cnt.first);
}
}
@@ -69,6 +71,8 @@ void CSVReporter::ReportRuns(const std::vector<Run>& reports) {
// check that all the current counters are saved in the name set
for (const auto& run : reports) {
for (const auto& cnt : run.counters) {
+ if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second")
+ continue;
CHECK(user_counter_names_.find(cnt.first) != user_counter_names_.end())
<< "All counters must be present in each run. "
<< "Counter named \"" << cnt.first
@@ -88,7 +92,7 @@ void CSVReporter::PrintRunData(const Run& run) {
// Field with embedded double-quote characters must be doubled and the field
// delimited with double-quotes.
- std::string name = run.benchmark_name;
+ std::string name = run.benchmark_name();
ReplaceAll(&name, "\"", "\"\"");
Out << '"' << name << "\",";
if (run.error_occurred) {
@@ -117,12 +121,12 @@ void CSVReporter::PrintRunData(const Run& run) {
}
Out << ",";
- if (run.bytes_per_second > 0.0) {
- Out << run.bytes_per_second;
+ if (run.counters.find("bytes_per_second") != run.counters.end()) {
+ Out << run.counters.at("bytes_per_second");
}
Out << ",";
- if (run.items_per_second > 0.0) {
- Out << run.items_per_second;
+ if (run.counters.find("items_per_second") != run.counters.end()) {
+ Out << run.counters.at("items_per_second");
}
Out << ",";
if (!run.report_label.empty()) {
diff --git a/utils/google-benchmark/src/cycleclock.h b/utils/google-benchmark/src/cycleclock.h
index 00d576416760..f5e37b011b9f 100644
--- a/utils/google-benchmark/src/cycleclock.h
+++ b/utils/google-benchmark/src/cycleclock.h
@@ -41,7 +41,7 @@ extern "C" uint64_t __rdtsc();
#pragma intrinsic(__rdtsc)
#endif
-#ifndef BENCHMARK_OS_WINDOWS
+#if !defined(BENCHMARK_OS_WINDOWS) || defined(BENCHMARK_OS_MINGW)
#include <sys/time.h>
#include <time.h>
#endif
diff --git a/utils/google-benchmark/src/internal_macros.h b/utils/google-benchmark/src/internal_macros.h
index b7e9203ff60e..5dbf4fd27521 100644
--- a/utils/google-benchmark/src/internal_macros.h
+++ b/utils/google-benchmark/src/internal_macros.h
@@ -11,9 +11,6 @@
#ifndef __has_feature
#define __has_feature(x) 0
#endif
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
#if defined(__clang__)
#if !defined(COMPILER_CLANG)
@@ -43,6 +40,9 @@
#define BENCHMARK_OS_CYGWIN 1
#elif defined(_WIN32)
#define BENCHMARK_OS_WINDOWS 1
+ #if defined(__MINGW32__)
+ #define BENCHMARK_OS_MINGW 1
+ #endif
#elif defined(__APPLE__)
#define BENCHMARK_OS_APPLE 1
#include "TargetConditionals.h"
@@ -87,14 +87,6 @@
#define BENCHMARK_MAYBE_UNUSED
#endif
-#if defined(COMPILER_GCC) || __has_builtin(__builtin_unreachable)
- #define BENCHMARK_UNREACHABLE() __builtin_unreachable()
-#elif defined(COMPILER_MSVC)
- #define BENCHMARK_UNREACHABLE() __assume(false)
-#else
- #define BENCHMARK_UNREACHABLE() ((void)0)
-#endif
-
// clang-format on
#endif // BENCHMARK_INTERNAL_MACROS_H_
diff --git a/utils/google-benchmark/src/json_reporter.cc b/utils/google-benchmark/src/json_reporter.cc
index 611605af6b56..7d01e8e4e316 100644
--- a/utils/google-benchmark/src/json_reporter.cc
+++ b/utils/google-benchmark/src/json_reporter.cc
@@ -77,8 +77,15 @@ bool JSONReporter::ReportContext(const Context& context) {
std::string walltime_value = LocalDateTimeString();
out << indent << FormatKV("date", walltime_value) << ",\n";
+ out << indent << FormatKV("host_name", context.sys_info.name) << ",\n";
+
if (Context::executable_name) {
- out << indent << FormatKV("executable", Context::executable_name) << ",\n";
+ // windows uses backslash for its path separator,
+ // which must be escaped in JSON otherwise it blows up conforming JSON
+ // decoders
+ std::string executable_name = Context::executable_name;
+ ReplaceAll(&executable_name, "\\", "\\\\");
+ out << indent << FormatKV("executable", executable_name) << ",\n";
}
CPUInfo const& info = context.cpu_info;
@@ -111,6 +118,12 @@ bool JSONReporter::ReportContext(const Context& context) {
}
indent = std::string(4, ' ');
out << indent << "],\n";
+ out << indent << "\"load_avg\": [";
+ for (auto it = info.load_avg.begin(); it != info.load_avg.end();) {
+ out << *it++;
+ if (it != info.load_avg.end()) out << ",";
+ }
+ out << "],\n";
#if defined(NDEBUG)
const char build_type[] = "release";
@@ -154,7 +167,20 @@ void JSONReporter::Finalize() {
void JSONReporter::PrintRunData(Run const& run) {
std::string indent(6, ' ');
std::ostream& out = GetOutputStream();
- out << indent << FormatKV("name", run.benchmark_name) << ",\n";
+ out << indent << FormatKV("name", run.benchmark_name()) << ",\n";
+ out << indent << FormatKV("run_name", run.run_name) << ",\n";
+ out << indent << FormatKV("run_type", [&run]() -> const char* {
+ switch (run.run_type) {
+ case BenchmarkReporter::Run::RT_Iteration:
+ return "iteration";
+ case BenchmarkReporter::Run::RT_Aggregate:
+ return "aggregate";
+ }
+ BENCHMARK_UNREACHABLE();
+ }()) << ",\n";
+ if (run.run_type == BenchmarkReporter::Run::RT_Aggregate) {
+ out << indent << FormatKV("aggregate_name", run.aggregate_name) << ",\n";
+ }
if (run.error_occurred) {
out << indent << FormatKV("error_occurred", run.error_occurred) << ",\n";
out << indent << FormatKV("error_message", run.error_message) << ",\n";
@@ -175,17 +201,16 @@ void JSONReporter::PrintRunData(Run const& run) {
} else if (run.report_rms) {
out << indent << FormatKV("rms", run.GetAdjustedCPUTime());
}
- if (run.bytes_per_second > 0.0) {
- out << ",\n"
- << indent << FormatKV("bytes_per_second", run.bytes_per_second);
- }
- if (run.items_per_second > 0.0) {
- out << ",\n"
- << indent << FormatKV("items_per_second", run.items_per_second);
- }
+
for (auto& c : run.counters) {
out << ",\n" << indent << FormatKV(c.first, c.second);
}
+
+ if (run.has_memory_result) {
+ out << ",\n" << indent << FormatKV("allocs_per_iter", run.allocs_per_iter);
+ out << ",\n" << indent << FormatKV("max_bytes_used", run.max_bytes_used);
+ }
+
if (!run.report_label.empty()) {
out << ",\n" << indent << FormatKV("label", run.report_label);
}
diff --git a/utils/google-benchmark/src/reporter.cc b/utils/google-benchmark/src/reporter.cc
index 541661a25f0a..59bc5f710231 100644
--- a/utils/google-benchmark/src/reporter.cc
+++ b/utils/google-benchmark/src/reporter.cc
@@ -22,6 +22,7 @@
#include <vector>
#include "check.h"
+#include "string_util.h"
namespace benchmark {
@@ -54,6 +55,14 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
Out << "\n";
}
}
+ if (!info.load_avg.empty()) {
+ Out << "Load Average: ";
+ for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {
+ Out << StrFormat("%.2f", *It++);
+ if (It != info.load_avg.end()) Out << ", ";
+ }
+ Out << "\n";
+ }
if (info.scaling_enabled) {
Out << "***WARNING*** CPU scaling is enabled, the benchmark "
@@ -70,7 +79,16 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
// No initializer because it's already initialized to NULL.
const char *BenchmarkReporter::Context::executable_name;
-BenchmarkReporter::Context::Context() : cpu_info(CPUInfo::Get()) {}
+BenchmarkReporter::Context::Context()
+ : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}
+
+std::string BenchmarkReporter::Run::benchmark_name() const {
+ std::string name = run_name;
+ if (run_type == RT_Aggregate) {
+ name += "_" + aggregate_name;
+ }
+ return name;
+}
double BenchmarkReporter::Run::GetAdjustedRealTime() const {
double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);
diff --git a/utils/google-benchmark/src/sleep.cc b/utils/google-benchmark/src/sleep.cc
index 54aa04a42247..1512ac90f7ea 100644
--- a/utils/google-benchmark/src/sleep.cc
+++ b/utils/google-benchmark/src/sleep.cc
@@ -21,7 +21,7 @@
#include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS
-#include <Windows.h>
+#include <windows.h>
#endif
namespace benchmark {
diff --git a/utils/google-benchmark/src/statistics.cc b/utils/google-benchmark/src/statistics.cc
index 612dda2d1a71..e821aec18b7c 100644
--- a/utils/google-benchmark/src/statistics.cc
+++ b/utils/google-benchmark/src/statistics.cc
@@ -91,13 +91,9 @@ std::vector<BenchmarkReporter::Run> ComputeStats(
// Accumulators.
std::vector<double> real_accumulated_time_stat;
std::vector<double> cpu_accumulated_time_stat;
- std::vector<double> bytes_per_second_stat;
- std::vector<double> items_per_second_stat;
real_accumulated_time_stat.reserve(reports.size());
cpu_accumulated_time_stat.reserve(reports.size());
- bytes_per_second_stat.reserve(reports.size());
- items_per_second_stat.reserve(reports.size());
// All repetitions should be run with the same number of iterations so we
// can take this information from the first benchmark.
@@ -123,13 +119,11 @@ std::vector<BenchmarkReporter::Run> ComputeStats(
// Populate the accumulators.
for (Run const& run : reports) {
- CHECK_EQ(reports[0].benchmark_name, run.benchmark_name);
+ CHECK_EQ(reports[0].benchmark_name(), run.benchmark_name());
CHECK_EQ(run_iterations, run.iterations);
if (run.error_occurred) continue;
real_accumulated_time_stat.emplace_back(run.real_accumulated_time);
cpu_accumulated_time_stat.emplace_back(run.cpu_accumulated_time);
- items_per_second_stat.emplace_back(run.items_per_second);
- bytes_per_second_stat.emplace_back(run.bytes_per_second);
// user counters
for (auto const& cnt : run.counters) {
auto it = counter_stats.find(cnt.first);
@@ -147,24 +141,43 @@ std::vector<BenchmarkReporter::Run> ComputeStats(
}
}
+ const double iteration_rescale_factor =
+ double(reports.size()) / double(run_iterations);
+
for (const auto& Stat : *reports[0].statistics) {
// Get the data from the accumulator to BenchmarkReporter::Run's.
Run data;
- data.benchmark_name = reports[0].benchmark_name + "_" + Stat.name_;
+ data.run_name = reports[0].benchmark_name();
+ data.run_type = BenchmarkReporter::Run::RT_Aggregate;
+ data.aggregate_name = Stat.name_;
data.report_label = report_label;
- data.iterations = run_iterations;
+
+ // It is incorrect to say that an aggregate is computed over
+ // run's iterations, because those iterations already got averaged.
+ // Similarly, if there are N repetitions with 1 iterations each,
+ // an aggregate will be computed over N measurements, not 1.
+ // Thus it is best to simply use the count of separate reports.
+ data.iterations = reports.size();
data.real_accumulated_time = Stat.compute_(real_accumulated_time_stat);
data.cpu_accumulated_time = Stat.compute_(cpu_accumulated_time_stat);
- data.bytes_per_second = Stat.compute_(bytes_per_second_stat);
- data.items_per_second = Stat.compute_(items_per_second_stat);
+
+ // We will divide these times by data.iterations when reporting, but the
+ // data.iterations is not nessesairly the scale of these measurements,
+ // because in each repetition, these timers are sum over all the iterations.
+ // And if we want to say that the stats are over N repetitions and not
+ // M iterations, we need to multiply these by (N/M).
+ data.real_accumulated_time *= iteration_rescale_factor;
+ data.cpu_accumulated_time *= iteration_rescale_factor;
data.time_unit = reports[0].time_unit;
// user counters
for (auto const& kv : counter_stats) {
+ // Do *NOT* rescale the custom counters. They are already properly scaled.
const auto uc_stat = Stat.compute_(kv.second.s);
- auto c = Counter(uc_stat, counter_stats[kv.first].c.flags);
+ auto c = Counter(uc_stat, counter_stats[kv.first].c.flags,
+ counter_stats[kv.first].c.oneK);
data.counters[kv.first] = c;
}
diff --git a/utils/google-benchmark/src/string_util.h b/utils/google-benchmark/src/string_util.h
index 4a5501273cf1..fc5f8b0304b0 100644
--- a/utils/google-benchmark/src/string_util.h
+++ b/utils/google-benchmark/src/string_util.h
@@ -12,7 +12,11 @@ void AppendHumanReadable(int n, std::string* str);
std::string HumanReadableNumber(double n, double one_k = 1024.0);
-std::string StrFormat(const char* format, ...);
+#ifdef __GNUC__
+__attribute__((format(printf, 1, 2)))
+#endif
+std::string
+StrFormat(const char* format, ...);
inline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
return out;
diff --git a/utils/google-benchmark/src/sysinfo.cc b/utils/google-benchmark/src/sysinfo.cc
index 73064b97ba22..c0c07e5e62af 100644
--- a/utils/google-benchmark/src/sysinfo.cc
+++ b/utils/google-benchmark/src/sysinfo.cc
@@ -15,10 +15,11 @@
#include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS
-#include <Shlwapi.h>
+#include <shlwapi.h>
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
-#include <VersionHelpers.h>
-#include <Windows.h>
+#include <versionhelpers.h>
+#include <windows.h>
+#include <codecvt>
#else
#include <fcntl.h>
#ifndef BENCHMARK_OS_FUCHSIA
@@ -52,6 +53,7 @@
#include <limits>
#include <memory>
#include <sstream>
+#include <locale>
#include "check.h"
#include "cycleclock.h"
@@ -288,7 +290,7 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizesMacOSX() {
std::string name;
std::string type;
int level;
- size_t num_sharing;
+ uint64_t num_sharing;
} Cases[] = {{"hw.l1dcachesize", "Data", 1, CacheCounts[1]},
{"hw.l1icachesize", "Instruction", 1, CacheCounts[1]},
{"hw.l2cachesize", "Unified", 2, CacheCounts[2]},
@@ -366,6 +368,35 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizes() {
#endif
}
+std::string GetSystemName() {
+#if defined(BENCHMARK_OS_WINDOWS)
+ std::string str;
+ const unsigned COUNT = MAX_COMPUTERNAME_LENGTH+1;
+ TCHAR hostname[COUNT] = {'\0'};
+ DWORD DWCOUNT = COUNT;
+ if (!GetComputerName(hostname, &DWCOUNT))
+ return std::string("");
+#ifndef UNICODE
+ str = std::string(hostname, DWCOUNT);
+#else
+ //Using wstring_convert, Is deprecated in C++17
+ using convert_type = std::codecvt_utf8<wchar_t>;
+ std::wstring_convert<convert_type, wchar_t> converter;
+ std::wstring wStr(hostname, DWCOUNT);
+ str = converter.to_bytes(wStr);
+#endif
+ return str;
+#else // defined(BENCHMARK_OS_WINDOWS)
+#ifdef BENCHMARK_OS_MACOSX //Mac Doesnt have HOST_NAME_MAX defined
+#define HOST_NAME_MAX 64
+#endif
+ char hostname[HOST_NAME_MAX];
+ int retVal = gethostname(hostname, HOST_NAME_MAX);
+ if (retVal != 0) return std::string("");
+ return std::string(hostname);
+#endif // Catch-all POSIX block.
+}
+
int GetNumCPUs() {
#ifdef BENCHMARK_HAS_SYSCTL
int NumCPU = -1;
@@ -404,7 +435,13 @@ int GetNumCPUs() {
if (ln.empty()) continue;
size_t SplitIdx = ln.find(':');
std::string value;
+#if defined(__s390__)
+ // s390 has another format in /proc/cpuinfo
+ // it needs to be parsed differently
+ if (SplitIdx != std::string::npos) value = ln.substr(Key.size()+1,SplitIdx-Key.size()-1);
+#else
if (SplitIdx != std::string::npos) value = ln.substr(SplitIdx + 1);
+#endif
if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) {
NumCPUs++;
if (!value.empty()) {
@@ -571,6 +608,24 @@ double GetCPUCyclesPerSecond() {
return static_cast<double>(cycleclock::Now() - start_ticks);
}
+std::vector<double> GetLoadAvg() {
+#if defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) || \
+ defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD || \
+ defined BENCHMARK_OS_OPENBSD
+ constexpr int kMaxSamples = 3;
+ std::vector<double> res(kMaxSamples, 0.0);
+ const int nelem = getloadavg(res.data(), kMaxSamples);
+ if (nelem < 1) {
+ res.clear();
+ } else {
+ res.resize(nelem);
+ }
+ return res;
+#else
+ return {};
+#endif
+}
+
} // end namespace
const CPUInfo& CPUInfo::Get() {
@@ -582,6 +637,14 @@ CPUInfo::CPUInfo()
: num_cpus(GetNumCPUs()),
cycles_per_second(GetCPUCyclesPerSecond()),
caches(GetCacheSizes()),
- scaling_enabled(CpuScalingEnabled(num_cpus)) {}
+ scaling_enabled(CpuScalingEnabled(num_cpus)),
+ load_avg(GetLoadAvg()) {}
+
+
+const SystemInfo& SystemInfo::Get() {
+ static const SystemInfo* info = new SystemInfo();
+ return *info;
+}
+SystemInfo::SystemInfo() : name(GetSystemName()) {}
} // end namespace benchmark
diff --git a/utils/google-benchmark/src/thread_manager.h b/utils/google-benchmark/src/thread_manager.h
index 82b4d72b62fb..6e274c7ea6bc 100644
--- a/utils/google-benchmark/src/thread_manager.h
+++ b/utils/google-benchmark/src/thread_manager.h
@@ -42,8 +42,6 @@ class ThreadManager {
double real_time_used = 0;
double cpu_time_used = 0;
double manual_time_used = 0;
- int64_t bytes_processed = 0;
- int64_t items_processed = 0;
int64_t complexity_n = 0;
std::string report_label_;
std::string error_message_;
diff --git a/utils/google-benchmark/src/timers.cc b/utils/google-benchmark/src/timers.cc
index 2010e2450b4a..7613ff92c6ef 100644
--- a/utils/google-benchmark/src/timers.cc
+++ b/utils/google-benchmark/src/timers.cc
@@ -16,10 +16,10 @@
#include "internal_macros.h"
#ifdef BENCHMARK_OS_WINDOWS
-#include <Shlwapi.h>
+#include <shlwapi.h>
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
-#include <VersionHelpers.h>
-#include <Windows.h>
+#include <versionhelpers.h>
+#include <windows.h>
#else
#include <fcntl.h>
#ifndef BENCHMARK_OS_FUCHSIA
diff --git a/utils/google-benchmark/test/AssemblyTests.cmake b/utils/google-benchmark/test/AssemblyTests.cmake
new file mode 100644
index 000000000000..3d078586f1de
--- /dev/null
+++ b/utils/google-benchmark/test/AssemblyTests.cmake
@@ -0,0 +1,46 @@
+
+include(split_list)
+
+set(ASM_TEST_FLAGS "")
+check_cxx_compiler_flag(-O3 BENCHMARK_HAS_O3_FLAG)
+if (BENCHMARK_HAS_O3_FLAG)
+ list(APPEND ASM_TEST_FLAGS -O3)
+endif()
+
+check_cxx_compiler_flag(-g0 BENCHMARK_HAS_G0_FLAG)
+if (BENCHMARK_HAS_G0_FLAG)
+ list(APPEND ASM_TEST_FLAGS -g0)
+endif()
+
+check_cxx_compiler_flag(-fno-stack-protector BENCHMARK_HAS_FNO_STACK_PROTECTOR_FLAG)
+if (BENCHMARK_HAS_FNO_STACK_PROTECTOR_FLAG)
+ list(APPEND ASM_TEST_FLAGS -fno-stack-protector)
+endif()
+
+split_list(ASM_TEST_FLAGS)
+string(TOUPPER "${CMAKE_CXX_COMPILER_ID}" ASM_TEST_COMPILER)
+
+macro(add_filecheck_test name)
+ cmake_parse_arguments(ARG "" "" "CHECK_PREFIXES" ${ARGV})
+ add_library(${name} OBJECT ${name}.cc)
+ set_target_properties(${name} PROPERTIES COMPILE_FLAGS "-S ${ASM_TEST_FLAGS}")
+ set(ASM_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${name}.s")
+ add_custom_target(copy_${name} ALL
+ COMMAND ${PROJECT_SOURCE_DIR}/tools/strip_asm.py
+ $<TARGET_OBJECTS:${name}>
+ ${ASM_OUTPUT_FILE}
+ BYPRODUCTS ${ASM_OUTPUT_FILE})
+ add_dependencies(copy_${name} ${name})
+ if (NOT ARG_CHECK_PREFIXES)
+ set(ARG_CHECK_PREFIXES "CHECK")
+ endif()
+ foreach(prefix ${ARG_CHECK_PREFIXES})
+ add_test(NAME run_${name}_${prefix}
+ COMMAND
+ ${LLVM_FILECHECK_EXE} ${name}.cc
+ --input-file=${ASM_OUTPUT_FILE}
+ --check-prefixes=CHECK,CHECK-${ASM_TEST_COMPILER}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ endforeach()
+endmacro()
+
diff --git a/utils/google-benchmark/test/CMakeLists.txt b/utils/google-benchmark/test/CMakeLists.txt
index f49ca5148f48..f15ce2081899 100644
--- a/utils/google-benchmark/test/CMakeLists.txt
+++ b/utils/google-benchmark/test/CMakeLists.txt
@@ -125,9 +125,21 @@ add_test(templated_fixture_test templated_fixture_test --benchmark_min_time=0.01
compile_output_test(user_counters_test)
add_test(user_counters_test user_counters_test --benchmark_min_time=0.01)
+compile_output_test(report_aggregates_only_test)
+add_test(report_aggregates_only_test report_aggregates_only_test --benchmark_min_time=0.01)
+
+compile_output_test(display_aggregates_only_test)
+add_test(display_aggregates_only_test display_aggregates_only_test --benchmark_min_time=0.01)
+
compile_output_test(user_counters_tabular_test)
add_test(user_counters_tabular_test user_counters_tabular_test --benchmark_counters_tabular=true --benchmark_min_time=0.01)
+compile_output_test(user_counters_thousands_test)
+add_test(user_counters_thousands_test user_counters_thousands_test --benchmark_min_time=0.01)
+
+compile_output_test(memory_manager_test)
+add_test(memory_manager_test memory_manager_test --benchmark_min_time=0.01)
+
check_cxx_compiler_flag(-std=c++03 BENCHMARK_HAS_CXX03_FLAG)
if (BENCHMARK_HAS_CXX03_FLAG)
compile_benchmark_test(cxx03_test)
diff --git a/utils/google-benchmark/test/complexity_test.cc b/utils/google-benchmark/test/complexity_test.cc
index 5f91660898be..323ddfe7ac59 100644
--- a/utils/google-benchmark/test/complexity_test.cc
+++ b/utils/google-benchmark/test/complexity_test.cc
@@ -12,9 +12,10 @@ namespace {
#define ADD_COMPLEXITY_CASES(...) \
int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__)
-int AddComplexityTest(std::string big_o_test_name, std::string rms_test_name,
- std::string big_o) {
- SetSubstitutions({{"%bigo_name", big_o_test_name},
+int AddComplexityTest(std::string test_name, std::string big_o_test_name,
+ std::string rms_test_name, std::string big_o) {
+ SetSubstitutions({{"%name", test_name},
+ {"%bigo_name", big_o_test_name},
{"%rms_name", rms_test_name},
{"%bigo_str", "[ ]* %float " + big_o},
{"%bigo", big_o},
@@ -25,12 +26,18 @@ int AddComplexityTest(std::string big_o_test_name, std::string rms_test_name,
{"^%bigo_name", MR_Not}, // Assert we we didn't only matched a name.
{"^%rms_name %rms %rms[ ]*$", MR_Next}});
AddCases(TC_JSONOut, {{"\"name\": \"%bigo_name\",$"},
+ {"\"run_name\": \"%name\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"BigO\",$", MR_Next},
{"\"cpu_coefficient\": %float,$", MR_Next},
{"\"real_coefficient\": %float,$", MR_Next},
{"\"big_o\": \"%bigo\",$", MR_Next},
{"\"time_unit\": \"ns\"$", MR_Next},
{"}", MR_Next},
{"\"name\": \"%rms_name\",$"},
+ {"\"run_name\": \"%name\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"RMS\",$", MR_Next},
{"\"rms\": %float$", MR_Next},
{"}", MR_Next}});
AddCases(TC_CSVOut, {{"^\"%bigo_name\",,%float,%float,%bigo,,,,,$"},
@@ -59,6 +66,7 @@ BENCHMARK(BM_Complexity_O1)->Range(1, 1 << 18)->Complexity([](int64_t) {
return 1.0;
});
+const char *one_test_name = "BM_Complexity_O1";
const char *big_o_1_test_name = "BM_Complexity_O1_BigO";
const char *rms_o_1_test_name = "BM_Complexity_O1_RMS";
const char *enum_big_o_1 = "\\([0-9]+\\)";
@@ -69,13 +77,16 @@ const char *auto_big_o_1 = "(\\([0-9]+\\))|(lgN)";
const char *lambda_big_o_1 = "f\\(N\\)";
// Add enum tests
-ADD_COMPLEXITY_CASES(big_o_1_test_name, rms_o_1_test_name, enum_big_o_1);
+ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
+ enum_big_o_1);
// Add auto enum tests
-ADD_COMPLEXITY_CASES(big_o_1_test_name, rms_o_1_test_name, auto_big_o_1);
+ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
+ auto_big_o_1);
// Add lambda tests
-ADD_COMPLEXITY_CASES(big_o_1_test_name, rms_o_1_test_name, lambda_big_o_1);
+ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
+ lambda_big_o_1);
// ========================================================================= //
// --------------------------- Testing BigO O(N) --------------------------- //
@@ -112,16 +123,19 @@ BENCHMARK(BM_Complexity_O_N)
->Range(1 << 10, 1 << 16)
->Complexity();
+const char *n_test_name = "BM_Complexity_O_N";
const char *big_o_n_test_name = "BM_Complexity_O_N_BigO";
const char *rms_o_n_test_name = "BM_Complexity_O_N_RMS";
const char *enum_auto_big_o_n = "N";
const char *lambda_big_o_n = "f\\(N\\)";
// Add enum tests
-ADD_COMPLEXITY_CASES(big_o_n_test_name, rms_o_n_test_name, enum_auto_big_o_n);
+ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name,
+ enum_auto_big_o_n);
// Add lambda tests
-ADD_COMPLEXITY_CASES(big_o_n_test_name, rms_o_n_test_name, lambda_big_o_n);
+ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name,
+ lambda_big_o_n);
// ========================================================================= //
// ------------------------- Testing BigO O(N*lgN) ------------------------- //
@@ -148,18 +162,19 @@ BENCHMARK(BM_Complexity_O_N_log_N)
->Range(1 << 10, 1 << 16)
->Complexity();
+const char *n_lg_n_test_name = "BM_Complexity_O_N_log_N";
const char *big_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N_BigO";
const char *rms_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N_RMS";
const char *enum_auto_big_o_n_lg_n = "NlgN";
const char *lambda_big_o_n_lg_n = "f\\(N\\)";
// Add enum tests
-ADD_COMPLEXITY_CASES(big_o_n_lg_n_test_name, rms_o_n_lg_n_test_name,
- enum_auto_big_o_n_lg_n);
+ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
+ rms_o_n_lg_n_test_name, enum_auto_big_o_n_lg_n);
// Add lambda tests
-ADD_COMPLEXITY_CASES(big_o_n_lg_n_test_name, rms_o_n_lg_n_test_name,
- lambda_big_o_n_lg_n);
+ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
+ rms_o_n_lg_n_test_name, lambda_big_o_n_lg_n);
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
diff --git a/utils/google-benchmark/test/display_aggregates_only_test.cc b/utils/google-benchmark/test/display_aggregates_only_test.cc
new file mode 100644
index 000000000000..3c36d3f03c11
--- /dev/null
+++ b/utils/google-benchmark/test/display_aggregates_only_test.cc
@@ -0,0 +1,43 @@
+
+#undef NDEBUG
+#include <cstdio>
+#include <string>
+
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+// Ok this test is super ugly. We want to check what happens with the file
+// reporter in the presence of DisplayAggregatesOnly().
+// We do not care about console output, the normal tests check that already.
+
+void BM_SummaryRepeat(benchmark::State& state) {
+ for (auto _ : state) {
+ }
+}
+BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->DisplayAggregatesOnly();
+
+int main(int argc, char* argv[]) {
+ const std::string output = GetFileReporterOutput(argc, argv);
+
+ if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 6 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3\"") != 3 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_mean\"") != 1 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_median\"") !=
+ 1 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"") !=
+ 1) {
+ std::cout << "Precondition mismatch. Expected to only find 6 "
+ "occurrences of \"BM_SummaryRepeat/repeats:3\" substring:\n"
+ "\"name\": \"BM_SummaryRepeat/repeats:3\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3_mean\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3_median\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"\nThe entire "
+ "output:\n";
+ std::cout << output;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/utils/google-benchmark/test/memory_manager_test.cc b/utils/google-benchmark/test/memory_manager_test.cc
new file mode 100644
index 000000000000..94be6083795e
--- /dev/null
+++ b/utils/google-benchmark/test/memory_manager_test.cc
@@ -0,0 +1,42 @@
+#include <memory>
+
+#include "../src/check.h"
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+class TestMemoryManager : public benchmark::MemoryManager {
+ void Start() {}
+ void Stop(Result* result) {
+ result->num_allocs = 42;
+ result->max_bytes_used = 42000;
+ }
+};
+
+void BM_empty(benchmark::State& state) {
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(state.iterations());
+ }
+}
+BENCHMARK(BM_empty);
+
+ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}});
+ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"},
+ {"\"run_name\": \"BM_empty\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"allocs_per_iter\": %float,$", MR_Next},
+ {"\"max_bytes_used\": 42000$", MR_Next},
+ {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}});
+
+
+int main(int argc, char *argv[]) {
+ std::unique_ptr<benchmark::MemoryManager> mm(new TestMemoryManager());
+
+ benchmark::RegisterMemoryManager(mm.get());
+ RunOutputTests(argc, argv);
+ benchmark::RegisterMemoryManager(nullptr);
+}
diff --git a/utils/google-benchmark/test/output_test.h b/utils/google-benchmark/test/output_test.h
index 31a919991f7c..9385761b214c 100644
--- a/utils/google-benchmark/test/output_test.h
+++ b/utils/google-benchmark/test/output_test.h
@@ -60,6 +60,13 @@ int SetSubstitutions(
// Run all output tests.
void RunOutputTests(int argc, char* argv[]);
+// Count the number of 'pat' substrings in the 'haystack' string.
+int SubstrCnt(const std::string& haystack, const std::string& pat);
+
+// Run registered benchmarks with file reporter enabled, and return the content
+// outputted by the file reporter.
+std::string GetFileReporterOutput(int argc, char* argv[]);
+
// ========================================================================= //
// ------------------------- Results checking ------------------------------ //
// ========================================================================= //
diff --git a/utils/google-benchmark/test/output_test_helper.cc b/utils/google-benchmark/test/output_test_helper.cc
index 394c4f5d1a26..5dc951d2bca8 100644
--- a/utils/google-benchmark/test/output_test_helper.cc
+++ b/utils/google-benchmark/test/output_test_helper.cc
@@ -1,8 +1,12 @@
+#include <cstdio>
#include <cstring>
+#include <fstream>
#include <iostream>
#include <map>
#include <memory>
+#include <random>
#include <sstream>
+#include <streambuf>
#include "../src/benchmark_api_internal.h"
#include "../src/check.h" // NOTE: check.h is for internal use only!
@@ -35,15 +39,18 @@ SubMap& GetSubstitutions() {
// Don't use 'dec_re' from header because it may not yet be initialized.
// clang-format off
static std::string safe_dec_re = "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?";
+ static std::string time_re = "([0-9]+[.])?[0-9]+";
static SubMap map = {
{"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"},
// human-readable float
{"%hrfloat", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?[kMGTPEZYmunpfazy]?"},
{"%int", "[ ]*[0-9]+"},
{" %s ", "[ ]+"},
- {"%time", "[ ]*[0-9]{1,6} ns"},
- {"%console_report", "[ ]*[0-9]{1,6} ns [ ]*[0-9]{1,6} ns [ ]*[0-9]+"},
- {"%console_us_report", "[ ]*[0-9] us [ ]*[0-9] us [ ]*[0-9]+"},
+ {"%time", "[ ]*" + time_re + "[ ]+ns"},
+ {"%console_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns [ ]*[0-9]+"},
+ {"%console_time_only_report", "[ ]*" + time_re + "[ ]+ns [ ]*" + time_re + "[ ]+ns"},
+ {"%console_us_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us [ ]*[0-9]+"},
+ {"%console_us_time_only_report", "[ ]*" + time_re + "[ ]+us [ ]*" + time_re + "[ ]+us"},
{"%csv_header",
"name,iterations,real_time,cpu_time,time_unit,bytes_per_second,"
"items_per_second,label,error_occurred,error_message"},
@@ -202,7 +209,7 @@ void ResultsChecker::Add(const std::string& entry_pattern, ResultsCheckFn fn) {
void ResultsChecker::CheckResults(std::stringstream& output) {
// first reset the stream to the start
{
- auto start = std::ios::streampos(0);
+ auto start = std::stringstream::pos_type(0);
// clear before calling tellg()
output.clear();
// seek to zero only when needed
@@ -423,3 +430,76 @@ void RunOutputTests(int argc, char* argv[]) {
CHECK(std::strcmp(csv.name, "CSVReporter") == 0);
internal::GetResultsChecker().CheckResults(csv.out_stream);
}
+
+int SubstrCnt(const std::string& haystack, const std::string& pat) {
+ if (pat.length() == 0) return 0;
+ int count = 0;
+ for (size_t offset = haystack.find(pat); offset != std::string::npos;
+ offset = haystack.find(pat, offset + pat.length()))
+ ++count;
+ return count;
+}
+
+static char ToHex(int ch) {
+ return ch < 10 ? static_cast<char>('0' + ch)
+ : static_cast<char>('a' + (ch - 10));
+}
+
+static char RandomHexChar() {
+ static std::mt19937 rd{std::random_device{}()};
+ static std::uniform_int_distribution<int> mrand{0, 15};
+ return ToHex(mrand(rd));
+}
+
+static std::string GetRandomFileName() {
+ std::string model = "test.%%%%%%";
+ for (auto & ch : model) {
+ if (ch == '%')
+ ch = RandomHexChar();
+ }
+ return model;
+}
+
+static bool FileExists(std::string const& name) {
+ std::ifstream in(name.c_str());
+ return in.good();
+}
+
+static std::string GetTempFileName() {
+ // This function attempts to avoid race conditions where two tests
+ // create the same file at the same time. However, it still introduces races
+ // similar to tmpnam.
+ int retries = 3;
+ while (--retries) {
+ std::string name = GetRandomFileName();
+ if (!FileExists(name))
+ return name;
+ }
+ std::cerr << "Failed to create unique temporary file name" << std::endl;
+ std::abort();
+}
+
+std::string GetFileReporterOutput(int argc, char* argv[]) {
+ std::vector<char*> new_argv(argv, argv + argc);
+ assert(static_cast<decltype(new_argv)::size_type>(argc) == new_argv.size());
+
+ std::string tmp_file_name = GetTempFileName();
+ std::cout << "Will be using this as the tmp file: " << tmp_file_name << '\n';
+
+ std::string tmp = "--benchmark_out=";
+ tmp += tmp_file_name;
+ new_argv.emplace_back(const_cast<char*>(tmp.c_str()));
+
+ argc = int(new_argv.size());
+
+ benchmark::Initialize(&argc, new_argv.data());
+ benchmark::RunSpecifiedBenchmarks();
+
+ // Read the output back from the file, and delete the file.
+ std::ifstream tmp_stream(tmp_file_name);
+ std::string output = std::string((std::istreambuf_iterator<char>(tmp_stream)),
+ std::istreambuf_iterator<char>());
+ std::remove(tmp_file_name.c_str());
+
+ return output;
+}
diff --git a/utils/google-benchmark/test/register_benchmark_test.cc b/utils/google-benchmark/test/register_benchmark_test.cc
index 18de6d68e210..3ac5b21fb348 100644
--- a/utils/google-benchmark/test/register_benchmark_test.cc
+++ b/utils/google-benchmark/test/register_benchmark_test.cc
@@ -30,8 +30,8 @@ struct TestCase {
void CheckRun(Run const& run) const {
// clang-format off
- CHECK(name == run.benchmark_name) << "expected " << name << " got "
- << run.benchmark_name;
+ CHECK(name == run.benchmark_name()) << "expected " << name << " got "
+ << run.benchmark_name();
if (label) {
CHECK(run.report_label == label) << "expected " << label << " got "
<< run.report_label;
diff --git a/utils/google-benchmark/test/report_aggregates_only_test.cc b/utils/google-benchmark/test/report_aggregates_only_test.cc
new file mode 100644
index 000000000000..9646b9be534d
--- /dev/null
+++ b/utils/google-benchmark/test/report_aggregates_only_test.cc
@@ -0,0 +1,39 @@
+
+#undef NDEBUG
+#include <cstdio>
+#include <string>
+
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+// Ok this test is super ugly. We want to check what happens with the file
+// reporter in the presence of ReportAggregatesOnly().
+// We do not care about console output, the normal tests check that already.
+
+void BM_SummaryRepeat(benchmark::State& state) {
+ for (auto _ : state) {
+ }
+}
+BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly();
+
+int main(int argc, char* argv[]) {
+ const std::string output = GetFileReporterOutput(argc, argv);
+
+ if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 3 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_mean\"") != 1 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_median\"") !=
+ 1 ||
+ SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"") !=
+ 1) {
+ std::cout << "Precondition mismatch. Expected to only find three "
+ "occurrences of \"BM_SummaryRepeat/repeats:3\" substring:\n"
+ "\"name\": \"BM_SummaryRepeat/repeats:3_mean\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3_median\", "
+ "\"name\": \"BM_SummaryRepeat/repeats:3_stddev\"\nThe entire "
+ "output:\n";
+ std::cout << output;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/utils/google-benchmark/test/reporter_output_test.cc b/utils/google-benchmark/test/reporter_output_test.cc
index 1662fcb8b543..ec6d51b35917 100644
--- a/utils/google-benchmark/test/reporter_output_test.cc
+++ b/utils/google-benchmark/test/reporter_output_test.cc
@@ -17,18 +17,21 @@ static int AddContextCases() {
{
{"%int[-/]%int[-/]%int %int:%int:%int$", MR_Default},
{"Running .*/reporter_output_test(\\.exe)?$", MR_Next},
- {"Run on \\(%int X %float MHz CPU s\\)", MR_Next},
+ {"Run on \\(%int X %float MHz CPU s?\\)", MR_Next},
});
AddCases(TC_JSONOut,
{{"^\\{", MR_Default},
{"\"context\":", MR_Next},
{"\"date\": \"", MR_Next},
- {"\"executable\": \".*/reporter_output_test(\\.exe)?\",", MR_Next},
+ {"\"host_name\":", MR_Next},
+ {"\"executable\": \".*(/|\\\\)reporter_output_test(\\.exe)?\",",
+ MR_Next},
{"\"num_cpus\": %int,$", MR_Next},
{"\"mhz_per_cpu\": %float,$", MR_Next},
{"\"cpu_scaling_enabled\": ", MR_Next},
{"\"caches\": \\[$", MR_Next}});
- auto const& Caches = benchmark::CPUInfo::Get().caches;
+ auto const& Info = benchmark::CPUInfo::Get();
+ auto const& Caches = Info.caches;
if (!Caches.empty()) {
AddCases(TC_ConsoleErr, {{"CPU Caches:$", MR_Next}});
}
@@ -45,8 +48,13 @@ static int AddContextCases() {
{"\"num_sharing\": %int$", MR_Next},
{"}[,]{0,1}$", MR_Next}});
}
-
AddCases(TC_JSONOut, {{"],$"}});
+ auto const& LoadAvg = Info.load_avg;
+ if (!LoadAvg.empty()) {
+ AddCases(TC_ConsoleErr,
+ {{"Load Average: (%float, ){0,2}%float$", MR_Next}});
+ }
+ AddCases(TC_JSONOut, {{"\"load_avg\": \\[(%float,?){0,3}],$", MR_Next}});
return 0;
}
int dummy_register = AddContextCases();
@@ -64,6 +72,8 @@ BENCHMARK(BM_basic);
ADD_CASES(TC_ConsoleOut, {{"^BM_basic %console_report$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_basic\",$"},
+ {"\"run_name\": \"BM_basic\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -82,9 +92,11 @@ void BM_bytes_per_second(benchmark::State& state) {
}
BENCHMARK(BM_bytes_per_second);
-ADD_CASES(TC_ConsoleOut,
- {{"^BM_bytes_per_second %console_report +%float[kM]{0,1}B/s$"}});
+ADD_CASES(TC_ConsoleOut, {{"^BM_bytes_per_second %console_report "
+ "bytes_per_second=%float[kM]{0,1}/s$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_bytes_per_second\",$"},
+ {"\"run_name\": \"BM_bytes_per_second\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -104,9 +116,11 @@ void BM_items_per_second(benchmark::State& state) {
}
BENCHMARK(BM_items_per_second);
-ADD_CASES(TC_ConsoleOut,
- {{"^BM_items_per_second %console_report +%float[kM]{0,1} items/s$"}});
+ADD_CASES(TC_ConsoleOut, {{"^BM_items_per_second %console_report "
+ "items_per_second=%float[kM]{0,1}/s$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_items_per_second\",$"},
+ {"\"run_name\": \"BM_items_per_second\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -128,6 +142,8 @@ BENCHMARK(BM_label);
ADD_CASES(TC_ConsoleOut, {{"^BM_label %console_report some label$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_label\",$"},
+ {"\"run_name\": \"BM_label\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -149,6 +165,8 @@ void BM_error(benchmark::State& state) {
BENCHMARK(BM_error);
ADD_CASES(TC_ConsoleOut, {{"^BM_error[ ]+ERROR OCCURRED: 'message'$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_error\",$"},
+ {"\"run_name\": \"BM_error\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"error_occurred\": true,$", MR_Next},
{"\"error_message\": \"message\",$", MR_Next}});
@@ -165,7 +183,9 @@ void BM_no_arg_name(benchmark::State& state) {
}
BENCHMARK(BM_no_arg_name)->Arg(3);
ADD_CASES(TC_ConsoleOut, {{"^BM_no_arg_name/3 %console_report$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_no_arg_name/3\",$"}});
+ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_no_arg_name/3\",$"},
+ {"\"run_name\": \"BM_no_arg_name/3\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_no_arg_name/3\",%csv_report$"}});
// ========================================================================= //
@@ -178,7 +198,9 @@ void BM_arg_name(benchmark::State& state) {
}
BENCHMARK(BM_arg_name)->ArgName("first")->Arg(3);
ADD_CASES(TC_ConsoleOut, {{"^BM_arg_name/first:3 %console_report$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_arg_name/first:3\",$"}});
+ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_arg_name/first:3\",$"},
+ {"\"run_name\": \"BM_arg_name/first:3\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_arg_name/first:3\",%csv_report$"}});
// ========================================================================= //
@@ -192,10 +214,25 @@ void BM_arg_names(benchmark::State& state) {
BENCHMARK(BM_arg_names)->Args({2, 5, 4})->ArgNames({"first", "", "third"});
ADD_CASES(TC_ConsoleOut,
{{"^BM_arg_names/first:2/5/third:4 %console_report$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_arg_names/first:2/5/third:4\",$"}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_arg_names/first:2/5/third:4\",$"},
+ {"\"run_name\": \"BM_arg_names/first:2/5/third:4\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_arg_names/first:2/5/third:4\",%csv_report$"}});
// ========================================================================= //
+// ------------------------ Testing Big Args Output ------------------------ //
+// ========================================================================= //
+
+void BM_BigArgs(benchmark::State& state) {
+ for (auto _ : state) {
+ }
+}
+BENCHMARK(BM_BigArgs)->RangeMultiplier(2)->Range(1U << 30U, 1U << 31U);
+ADD_CASES(TC_ConsoleOut, {{"^BM_BigArgs/1073741824 %console_report$"},
+ {"^BM_BigArgs/2147483648 %console_report$"}});
+
+// ========================================================================= //
// ----------------------- Testing Complexity Output ----------------------- //
// ========================================================================= //
@@ -221,16 +258,33 @@ void BM_Repeat(benchmark::State& state) {
}
// need two repetitions min to be able to output any aggregate output
BENCHMARK(BM_Repeat)->Repetitions(2);
-ADD_CASES(TC_ConsoleOut, {{"^BM_Repeat/repeats:2 %console_report$"},
- {"^BM_Repeat/repeats:2 %console_report$"},
- {"^BM_Repeat/repeats:2_mean %console_report$"},
- {"^BM_Repeat/repeats:2_median %console_report$"},
- {"^BM_Repeat/repeats:2_stddev %console_report$"}});
+ADD_CASES(TC_ConsoleOut,
+ {{"^BM_Repeat/repeats:2 %console_report$"},
+ {"^BM_Repeat/repeats:2 %console_report$"},
+ {"^BM_Repeat/repeats:2_mean %console_time_only_report [ ]*2$"},
+ {"^BM_Repeat/repeats:2_median %console_time_only_report [ ]*2$"},
+ {"^BM_Repeat/repeats:2_stddev %console_time_only_report [ ]*2$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:2\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:2\"", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:2\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:2_mean\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:2_median\",$"},
- {"\"name\": \"BM_Repeat/repeats:2_stddev\",$"}});
+ {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"name\": \"BM_Repeat/repeats:2_stddev\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:2\",%csv_report$"},
{"^\"BM_Repeat/repeats:2\",%csv_report$"},
{"^\"BM_Repeat/repeats:2_mean\",%csv_report$"},
@@ -238,18 +292,37 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:2\",%csv_report$"},
{"^\"BM_Repeat/repeats:2_stddev\",%csv_report$"}});
// but for two repetitions, mean and median is the same, so let's repeat..
BENCHMARK(BM_Repeat)->Repetitions(3);
-ADD_CASES(TC_ConsoleOut, {{"^BM_Repeat/repeats:3 %console_report$"},
- {"^BM_Repeat/repeats:3 %console_report$"},
- {"^BM_Repeat/repeats:3 %console_report$"},
- {"^BM_Repeat/repeats:3_mean %console_report$"},
- {"^BM_Repeat/repeats:3_median %console_report$"},
- {"^BM_Repeat/repeats:3_stddev %console_report$"}});
+ADD_CASES(TC_ConsoleOut,
+ {{"^BM_Repeat/repeats:3 %console_report$"},
+ {"^BM_Repeat/repeats:3 %console_report$"},
+ {"^BM_Repeat/repeats:3 %console_report$"},
+ {"^BM_Repeat/repeats:3_mean %console_time_only_report [ ]*3$"},
+ {"^BM_Repeat/repeats:3_median %console_time_only_report [ ]*3$"},
+ {"^BM_Repeat/repeats:3_stddev %console_time_only_report [ ]*3$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:3\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:3\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:3\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:3_mean\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:3_median\",$"},
- {"\"name\": \"BM_Repeat/repeats:3_stddev\",$"}});
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"name\": \"BM_Repeat/repeats:3_stddev\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:3\",%csv_report$"},
{"^\"BM_Repeat/repeats:3\",%csv_report$"},
{"^\"BM_Repeat/repeats:3\",%csv_report$"},
@@ -258,20 +331,41 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:3\",%csv_report$"},
{"^\"BM_Repeat/repeats:3_stddev\",%csv_report$"}});
// median differs between even/odd number of repetitions, so just to be sure
BENCHMARK(BM_Repeat)->Repetitions(4);
-ADD_CASES(TC_ConsoleOut, {{"^BM_Repeat/repeats:4 %console_report$"},
- {"^BM_Repeat/repeats:4 %console_report$"},
- {"^BM_Repeat/repeats:4 %console_report$"},
- {"^BM_Repeat/repeats:4 %console_report$"},
- {"^BM_Repeat/repeats:4_mean %console_report$"},
- {"^BM_Repeat/repeats:4_median %console_report$"},
- {"^BM_Repeat/repeats:4_stddev %console_report$"}});
+ADD_CASES(TC_ConsoleOut,
+ {{"^BM_Repeat/repeats:4 %console_report$"},
+ {"^BM_Repeat/repeats:4 %console_report$"},
+ {"^BM_Repeat/repeats:4 %console_report$"},
+ {"^BM_Repeat/repeats:4 %console_report$"},
+ {"^BM_Repeat/repeats:4_mean %console_time_only_report [ ]*4$"},
+ {"^BM_Repeat/repeats:4_median %console_time_only_report [ ]*4$"},
+ {"^BM_Repeat/repeats:4_stddev %console_time_only_report [ ]*4$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Repeat/repeats:4\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:4\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:4\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:4\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:4_mean\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 4,$", MR_Next},
{"\"name\": \"BM_Repeat/repeats:4_median\",$"},
- {"\"name\": \"BM_Repeat/repeats:4_stddev\",$"}});
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 4,$", MR_Next},
+ {"\"name\": \"BM_Repeat/repeats:4_stddev\",$"},
+ {"\"run_name\": \"BM_Repeat/repeats:4\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 4,$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Repeat/repeats:4\",%csv_report$"},
{"^\"BM_Repeat/repeats:4\",%csv_report$"},
{"^\"BM_Repeat/repeats:4\",%csv_report$"},
@@ -288,7 +382,9 @@ void BM_RepeatOnce(benchmark::State& state) {
}
BENCHMARK(BM_RepeatOnce)->Repetitions(1)->ReportAggregatesOnly();
ADD_CASES(TC_ConsoleOut, {{"^BM_RepeatOnce/repeats:1 %console_report$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_RepeatOnce/repeats:1\",$"}});
+ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_RepeatOnce/repeats:1\",$"},
+ {"\"run_name\": \"BM_RepeatOnce/repeats:1\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_RepeatOnce/repeats:1\",%csv_report$"}});
// Test that non-aggregate data is not reported
@@ -297,20 +393,72 @@ void BM_SummaryRepeat(benchmark::State& state) {
}
}
BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly();
-ADD_CASES(TC_ConsoleOut,
+ADD_CASES(
+ TC_ConsoleOut,
+ {{".*BM_SummaryRepeat/repeats:3 ", MR_Not},
+ {"^BM_SummaryRepeat/repeats:3_mean %console_time_only_report [ ]*3$"},
+ {"^BM_SummaryRepeat/repeats:3_median %console_time_only_report [ ]*3$"},
+ {"^BM_SummaryRepeat/repeats:3_stddev %console_time_only_report [ ]*3$"}});
+ADD_CASES(TC_JSONOut,
{{".*BM_SummaryRepeat/repeats:3 ", MR_Not},
- {"^BM_SummaryRepeat/repeats:3_mean %console_report$"},
- {"^BM_SummaryRepeat/repeats:3_median %console_report$"},
- {"^BM_SummaryRepeat/repeats:3_stddev %console_report$"}});
-ADD_CASES(TC_JSONOut, {{".*BM_SummaryRepeat/repeats:3 ", MR_Not},
- {"\"name\": \"BM_SummaryRepeat/repeats:3_mean\",$"},
- {"\"name\": \"BM_SummaryRepeat/repeats:3_median\",$"},
- {"\"name\": \"BM_SummaryRepeat/repeats:3_stddev\",$"}});
+ {"\"name\": \"BM_SummaryRepeat/repeats:3_mean\",$"},
+ {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"name\": \"BM_SummaryRepeat/repeats:3_median\",$"},
+ {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"name\": \"BM_SummaryRepeat/repeats:3_stddev\",$"},
+ {"\"run_name\": \"BM_SummaryRepeat/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next}});
ADD_CASES(TC_CSVOut, {{".*BM_SummaryRepeat/repeats:3 ", MR_Not},
{"^\"BM_SummaryRepeat/repeats:3_mean\",%csv_report$"},
{"^\"BM_SummaryRepeat/repeats:3_median\",%csv_report$"},
{"^\"BM_SummaryRepeat/repeats:3_stddev\",%csv_report$"}});
+// Test that non-aggregate data is not displayed.
+// NOTE: this test is kinda bad. we are only testing the display output.
+// But we don't check that the file output still contains everything...
+void BM_SummaryDisplay(benchmark::State& state) {
+ for (auto _ : state) {
+ }
+}
+BENCHMARK(BM_SummaryDisplay)->Repetitions(2)->DisplayAggregatesOnly();
+ADD_CASES(
+ TC_ConsoleOut,
+ {{".*BM_SummaryDisplay/repeats:2 ", MR_Not},
+ {"^BM_SummaryDisplay/repeats:2_mean %console_time_only_report [ ]*2$"},
+ {"^BM_SummaryDisplay/repeats:2_median %console_time_only_report [ ]*2$"},
+ {"^BM_SummaryDisplay/repeats:2_stddev %console_time_only_report [ ]*2$"}});
+ADD_CASES(TC_JSONOut,
+ {{".*BM_SummaryDisplay/repeats:2 ", MR_Not},
+ {"\"name\": \"BM_SummaryDisplay/repeats:2_mean\",$"},
+ {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"name\": \"BM_SummaryDisplay/repeats:2_median\",$"},
+ {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"name\": \"BM_SummaryDisplay/repeats:2_stddev\",$"},
+ {"\"run_name\": \"BM_SummaryDisplay/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next}});
+ADD_CASES(TC_CSVOut,
+ {{".*BM_SummaryDisplay/repeats:2 ", MR_Not},
+ {"^\"BM_SummaryDisplay/repeats:2_mean\",%csv_report$"},
+ {"^\"BM_SummaryDisplay/repeats:2_median\",%csv_report$"},
+ {"^\"BM_SummaryDisplay/repeats:2_stddev\",%csv_report$"}});
+
+// Test repeats with custom time unit.
void BM_RepeatTimeUnit(benchmark::State& state) {
for (auto _ : state) {
}
@@ -319,18 +467,34 @@ BENCHMARK(BM_RepeatTimeUnit)
->Repetitions(3)
->ReportAggregatesOnly()
->Unit(benchmark::kMicrosecond);
-ADD_CASES(TC_ConsoleOut,
+ADD_CASES(
+ TC_ConsoleOut,
+ {{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not},
+ {"^BM_RepeatTimeUnit/repeats:3_mean %console_us_time_only_report [ ]*3$"},
+ {"^BM_RepeatTimeUnit/repeats:3_median %console_us_time_only_report [ "
+ "]*3$"},
+ {"^BM_RepeatTimeUnit/repeats:3_stddev %console_us_time_only_report [ "
+ "]*3$"}});
+ADD_CASES(TC_JSONOut,
{{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not},
- {"^BM_RepeatTimeUnit/repeats:3_mean %console_us_report$"},
- {"^BM_RepeatTimeUnit/repeats:3_median %console_us_report$"},
- {"^BM_RepeatTimeUnit/repeats:3_stddev %console_us_report$"}});
-ADD_CASES(TC_JSONOut, {{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not},
- {"\"name\": \"BM_RepeatTimeUnit/repeats:3_mean\",$"},
- {"\"time_unit\": \"us\",?$"},
- {"\"name\": \"BM_RepeatTimeUnit/repeats:3_median\",$"},
- {"\"time_unit\": \"us\",?$"},
- {"\"name\": \"BM_RepeatTimeUnit/repeats:3_stddev\",$"},
- {"\"time_unit\": \"us\",?$"}});
+ {"\"name\": \"BM_RepeatTimeUnit/repeats:3_mean\",$"},
+ {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"time_unit\": \"us\",?$"},
+ {"\"name\": \"BM_RepeatTimeUnit/repeats:3_median\",$"},
+ {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"time_unit\": \"us\",?$"},
+ {"\"name\": \"BM_RepeatTimeUnit/repeats:3_stddev\",$"},
+ {"\"run_name\": \"BM_RepeatTimeUnit/repeats:3\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"time_unit\": \"us\",?$"}});
ADD_CASES(TC_CSVOut,
{{".*BM_RepeatTimeUnit/repeats:3 ", MR_Not},
{"^\"BM_RepeatTimeUnit/repeats:3_mean\",%csv_us_report$"},
@@ -346,37 +510,92 @@ const auto UserStatistics = [](const std::vector<double>& v) {
};
void BM_UserStats(benchmark::State& state) {
for (auto _ : state) {
+ state.SetIterationTime(150 / 10e8);
}
}
// clang-format off
BENCHMARK(BM_UserStats)
->Repetitions(3)
+ ->Iterations(5)
+ ->UseManualTime()
->ComputeStatistics("", UserStatistics);
// clang-format on
// check that user-provided stats is calculated, and is after the default-ones
// empty string as name is intentional, it would sort before anything else
-ADD_CASES(TC_ConsoleOut, {{"^BM_UserStats/repeats:3 %console_report$"},
- {"^BM_UserStats/repeats:3 %console_report$"},
- {"^BM_UserStats/repeats:3 %console_report$"},
- {"^BM_UserStats/repeats:3_mean %console_report$"},
- {"^BM_UserStats/repeats:3_median %console_report$"},
- {"^BM_UserStats/repeats:3_stddev %console_report$"},
- {"^BM_UserStats/repeats:3_ %console_report$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_UserStats/repeats:3\",$"},
- {"\"name\": \"BM_UserStats/repeats:3\",$"},
- {"\"name\": \"BM_UserStats/repeats:3\",$"},
- {"\"name\": \"BM_UserStats/repeats:3_mean\",$"},
- {"\"name\": \"BM_UserStats/repeats:3_median\",$"},
- {"\"name\": \"BM_UserStats/repeats:3_stddev\",$"},
- {"\"name\": \"BM_UserStats/repeats:3_\",$"}});
-ADD_CASES(TC_CSVOut, {{"^\"BM_UserStats/repeats:3\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3_mean\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3_median\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3_stddev\",%csv_report$"},
- {"^\"BM_UserStats/repeats:3_\",%csv_report$"}});
+ADD_CASES(TC_ConsoleOut, {{"^BM_UserStats/iterations:5/repeats:3/manual_time [ "
+ "]* 150 ns %time [ ]*5$"},
+ {"^BM_UserStats/iterations:5/repeats:3/manual_time [ "
+ "]* 150 ns %time [ ]*5$"},
+ {"^BM_UserStats/iterations:5/repeats:3/manual_time [ "
+ "]* 150 ns %time [ ]*5$"},
+ {"^BM_UserStats/iterations:5/repeats:3/"
+ "manual_time_mean [ ]* 150 ns %time [ ]*3$"},
+ {"^BM_UserStats/iterations:5/repeats:3/"
+ "manual_time_median [ ]* 150 ns %time [ ]*3$"},
+ {"^BM_UserStats/iterations:5/repeats:3/"
+ "manual_time_stddev [ ]* 0.000 ns %time [ ]*3$"},
+ {"^BM_UserStats/iterations:5/repeats:3/manual_time_ "
+ "[ ]* 150 ns %time [ ]*3$"}});
+ADD_CASES(
+ TC_JSONOut,
+ {{"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": 5,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": 5,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": 5,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_mean\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_median\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_stddev\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"name\": \"BM_UserStats/iterations:5/repeats:3/manual_time_\",$"},
+ {"\"run_name\": \"BM_UserStats/iterations:5/repeats:3/manual_time\",$",
+ MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"\",$", MR_Next},
+ {"\"iterations\": 3,$", MR_Next},
+ {"\"real_time\": 1\\.5(0)*e\\+(0)*2,$", MR_Next}});
+ADD_CASES(
+ TC_CSVOut,
+ {{"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/manual_time\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/manual_time_mean\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/"
+ "manual_time_median\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/"
+ "manual_time_stddev\",%csv_report$"},
+ {"^\"BM_UserStats/iterations:5/repeats:3/manual_time_\",%csv_report$"}});
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
diff --git a/utils/google-benchmark/test/skip_with_error_test.cc b/utils/google-benchmark/test/skip_with_error_test.cc
index 39785fb7f6d8..06579772ff77 100644
--- a/utils/google-benchmark/test/skip_with_error_test.cc
+++ b/utils/google-benchmark/test/skip_with_error_test.cc
@@ -33,8 +33,8 @@ struct TestCase {
typedef benchmark::BenchmarkReporter::Run Run;
void CheckRun(Run const& run) const {
- CHECK(name == run.benchmark_name)
- << "expected " << name << " got " << run.benchmark_name;
+ CHECK(name == run.benchmark_name())
+ << "expected " << name << " got " << run.benchmark_name();
CHECK(error_occurred == run.error_occurred);
CHECK(error_message == run.error_message);
if (error_occurred) {
diff --git a/utils/google-benchmark/test/string_util_gtest.cc b/utils/google-benchmark/test/string_util_gtest.cc
index 4c81734cf8a3..2c5d073f613b 100644
--- a/utils/google-benchmark/test/string_util_gtest.cc
+++ b/utils/google-benchmark/test/string_util_gtest.cc
@@ -9,56 +9,56 @@ namespace {
TEST(StringUtilTest, stoul) {
{
size_t pos = 0;
- EXPECT_EQ(0, benchmark::stoul("0", &pos));
- EXPECT_EQ(1, pos);
+ EXPECT_EQ(0ul, benchmark::stoul("0", &pos));
+ EXPECT_EQ(1ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(7, benchmark::stoul("7", &pos));
- EXPECT_EQ(1, pos);
+ EXPECT_EQ(7ul, benchmark::stoul("7", &pos));
+ EXPECT_EQ(1ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(135, benchmark::stoul("135", &pos));
- EXPECT_EQ(3, pos);
+ EXPECT_EQ(135ul, benchmark::stoul("135", &pos));
+ EXPECT_EQ(3ul, pos);
}
#if ULONG_MAX == 0xFFFFFFFFul
{
size_t pos = 0;
EXPECT_EQ(0xFFFFFFFFul, benchmark::stoul("4294967295", &pos));
- EXPECT_EQ(10, pos);
+ EXPECT_EQ(10ul, pos);
}
#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFFul
{
size_t pos = 0;
EXPECT_EQ(0xFFFFFFFFFFFFFFFFul, benchmark::stoul("18446744073709551615", &pos));
- EXPECT_EQ(20, pos);
+ EXPECT_EQ(20ul, pos);
}
#endif
{
size_t pos = 0;
- EXPECT_EQ(10, benchmark::stoul("1010", &pos, 2));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(10ul, benchmark::stoul("1010", &pos, 2));
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(520, benchmark::stoul("1010", &pos, 8));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(520ul, benchmark::stoul("1010", &pos, 8));
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(1010, benchmark::stoul("1010", &pos, 10));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(1010ul, benchmark::stoul("1010", &pos, 10));
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(4112, benchmark::stoul("1010", &pos, 16));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4112ul, benchmark::stoul("1010", &pos, 16));
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
- EXPECT_EQ(0xBEEF, benchmark::stoul("BEEF", &pos, 16));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(0xBEEFul, benchmark::stoul("BEEF", &pos, 16));
+ EXPECT_EQ(4ul, pos);
}
{
ASSERT_THROW(benchmark::stoul("this is a test"), std::invalid_argument);
@@ -69,42 +69,42 @@ TEST(StringUtilTest, stoi) {
{
size_t pos = 0;
EXPECT_EQ(0, benchmark::stoi("0", &pos));
- EXPECT_EQ(1, pos);
+ EXPECT_EQ(1ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(-17, benchmark::stoi("-17", &pos));
- EXPECT_EQ(3, pos);
+ EXPECT_EQ(3ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(1357, benchmark::stoi("1357", &pos));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(10, benchmark::stoi("1010", &pos, 2));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(520, benchmark::stoi("1010", &pos, 8));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(1010, benchmark::stoi("1010", &pos, 10));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(4112, benchmark::stoi("1010", &pos, 16));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(0xBEEF, benchmark::stoi("BEEF", &pos, 16));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
ASSERT_THROW(benchmark::stoi("this is a test"), std::invalid_argument);
@@ -115,28 +115,28 @@ TEST(StringUtilTest, stod) {
{
size_t pos = 0;
EXPECT_EQ(0.0, benchmark::stod("0", &pos));
- EXPECT_EQ(1, pos);
+ EXPECT_EQ(1ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(-84.0, benchmark::stod("-84", &pos));
- EXPECT_EQ(3, pos);
+ EXPECT_EQ(3ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(1234.0, benchmark::stod("1234", &pos));
- EXPECT_EQ(4, pos);
+ EXPECT_EQ(4ul, pos);
}
{
size_t pos = 0;
EXPECT_EQ(1.5, benchmark::stod("1.5", &pos));
- EXPECT_EQ(3, pos);
+ EXPECT_EQ(3ul, pos);
}
{
size_t pos = 0;
/* Note: exactly representable as double */
EXPECT_EQ(-1.25e+9, benchmark::stod("-1.25e+9", &pos));
- EXPECT_EQ(8, pos);
+ EXPECT_EQ(8ul, pos);
}
{
ASSERT_THROW(benchmark::stod("this is a test"), std::invalid_argument);
diff --git a/utils/google-benchmark/test/user_counters_tabular_test.cc b/utils/google-benchmark/test/user_counters_tabular_test.cc
index 4f126b6d978c..030e98916c3d 100644
--- a/utils/google-benchmark/test/user_counters_tabular_test.cc
+++ b/utils/google-benchmark/test/user_counters_tabular_test.cc
@@ -69,18 +69,21 @@ void BM_Counters_Tabular(benchmark::State& state) {
});
}
BENCHMARK(BM_Counters_Tabular)->ThreadRange(1, 16);
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Tabular/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"Bar\": %float,$", MR_Next},
- {"\"Bat\": %float,$", MR_Next},
- {"\"Baz\": %float,$", MR_Next},
- {"\"Foo\": %float,$", MR_Next},
- {"\"Frob\": %float,$", MR_Next},
- {"\"Lob\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Tabular/threads:%int\",$"},
+ {"\"run_name\": \"BM_Counters_Tabular/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"Bar\": %float,$", MR_Next},
+ {"\"Bat\": %float,$", MR_Next},
+ {"\"Baz\": %float,$", MR_Next},
+ {"\"Foo\": %float,$", MR_Next},
+ {"\"Frob\": %float,$", MR_Next},
+ {"\"Lob\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Tabular/threads:%int\",%csv_report,"
"%float,%float,%float,%float,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -113,18 +116,22 @@ void BM_CounterRates_Tabular(benchmark::State& state) {
});
}
BENCHMARK(BM_CounterRates_Tabular)->ThreadRange(1, 16);
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_CounterRates_Tabular/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"Bar\": %float,$", MR_Next},
- {"\"Bat\": %float,$", MR_Next},
- {"\"Baz\": %float,$", MR_Next},
- {"\"Foo\": %float,$", MR_Next},
- {"\"Frob\": %float,$", MR_Next},
- {"\"Lob\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_CounterRates_Tabular/threads:%int\",$"},
+ {"\"run_name\": \"BM_CounterRates_Tabular/threads:%int\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"Bar\": %float,$", MR_Next},
+ {"\"Bat\": %float,$", MR_Next},
+ {"\"Baz\": %float,$", MR_Next},
+ {"\"Foo\": %float,$", MR_Next},
+ {"\"Frob\": %float,$", MR_Next},
+ {"\"Lob\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_CounterRates_Tabular/threads:%int\",%csv_report,"
"%float,%float,%float,%float,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -157,15 +164,18 @@ void BM_CounterSet0_Tabular(benchmark::State& state) {
});
}
BENCHMARK(BM_CounterSet0_Tabular)->ThreadRange(1, 16);
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_CounterSet0_Tabular/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"Bar\": %float,$", MR_Next},
- {"\"Baz\": %float,$", MR_Next},
- {"\"Foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_CounterSet0_Tabular/threads:%int\",$"},
+ {"\"run_name\": \"BM_CounterSet0_Tabular/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"Bar\": %float,$", MR_Next},
+ {"\"Baz\": %float,$", MR_Next},
+ {"\"Foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet0_Tabular/threads:%int\",%csv_report,"
"%float,,%float,%float,,"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -189,15 +199,18 @@ void BM_CounterSet1_Tabular(benchmark::State& state) {
});
}
BENCHMARK(BM_CounterSet1_Tabular)->ThreadRange(1, 16);
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_CounterSet1_Tabular/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"Bar\": %float,$", MR_Next},
- {"\"Baz\": %float,$", MR_Next},
- {"\"Foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_CounterSet1_Tabular/threads:%int\",$"},
+ {"\"run_name\": \"BM_CounterSet1_Tabular/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"Bar\": %float,$", MR_Next},
+ {"\"Baz\": %float,$", MR_Next},
+ {"\"Foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet1_Tabular/threads:%int\",%csv_report,"
"%float,,%float,%float,,"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -225,15 +238,18 @@ void BM_CounterSet2_Tabular(benchmark::State& state) {
});
}
BENCHMARK(BM_CounterSet2_Tabular)->ThreadRange(1, 16);
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_CounterSet2_Tabular/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"Bat\": %float,$", MR_Next},
- {"\"Baz\": %float,$", MR_Next},
- {"\"Foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_CounterSet2_Tabular/threads:%int\",$"},
+ {"\"run_name\": \"BM_CounterSet2_Tabular/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"Bat\": %float,$", MR_Next},
+ {"\"Baz\": %float,$", MR_Next},
+ {"\"Foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_CounterSet2_Tabular/threads:%int\",%csv_report,"
",%float,%float,%float,,"}});
// VS2013 does not allow this function to be passed as a lambda argument
diff --git a/utils/google-benchmark/test/user_counters_test.cc b/utils/google-benchmark/test/user_counters_test.cc
index 7f7ccb9f77a3..bb0d6b4c5a91 100644
--- a/utils/google-benchmark/test/user_counters_test.cc
+++ b/utils/google-benchmark/test/user_counters_test.cc
@@ -32,6 +32,8 @@ BENCHMARK(BM_Counters_Simple);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_Simple %console_report bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Simple\",$"},
+ {"\"run_name\": \"BM_Counters_Simple\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -66,19 +68,22 @@ void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
state.SetItemsProcessed(150);
}
BENCHMARK(BM_Counters_WithBytesAndItemsPSec);
-ADD_CASES(TC_ConsoleOut,
- {{"^BM_Counters_WithBytesAndItemsPSec %console_report "
- "bar=%hrfloat foo=%hrfloat +%hrfloatB/s +%hrfloat items/s$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bytes_per_second\": %float,$", MR_Next},
- {"\"items_per_second\": %float,$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_WithBytesAndItemsPSec %console_report "
+ "bar=%hrfloat bytes_per_second=%hrfloat/s "
+ "foo=%hrfloat items_per_second=%hrfloat/s$"}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"},
+ {"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"bytes_per_second\": %float,$", MR_Next},
+ {"\"foo\": %float,$", MR_Next},
+ {"\"items_per_second\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec\","
"%csv_bytes_items_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -110,6 +115,8 @@ ADD_CASES(
TC_ConsoleOut,
{{"^BM_Counters_Rate %console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Rate\",$"},
+ {"\"run_name\": \"BM_Counters_Rate\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -141,14 +148,17 @@ void BM_Counters_Threads(benchmark::State& state) {
BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
+ {"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}});
@@ -174,14 +184,17 @@ void BM_Counters_AvgThreads(benchmark::State& state) {
BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int "
"%console_report bar=%hrfloat foo=%hrfloat$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
+ {"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}});
@@ -210,6 +223,9 @@ ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"},
+ {"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -242,14 +258,17 @@ void BM_Counters_IterationInvariant(benchmark::State& state) {
BENCHMARK(BM_Counters_IterationInvariant);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_IterationInvariant %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_IterationInvariant\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_IterationInvariant\",$"},
+ {"\"run_name\": \"BM_Counters_IterationInvariant\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut,
{{"^\"BM_Counters_IterationInvariant\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -281,6 +300,9 @@ ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kIsIterationInvariantRate "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_kIsIterationInvariantRate\",$"},
+ {"\"run_name\": \"BM_Counters_kIsIterationInvariantRate\",$",
+ MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
@@ -316,14 +338,17 @@ void BM_Counters_AvgIterations(benchmark::State& state) {
BENCHMARK(BM_Counters_AvgIterations);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgIterations %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_AvgIterations\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_AvgIterations\",$"},
+ {"\"run_name\": \"BM_Counters_AvgIterations\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut,
{{"^\"BM_Counters_AvgIterations\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
@@ -351,14 +376,17 @@ void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
BENCHMARK(BM_Counters_kAvgIterationsRate);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
-ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_kAvgIterationsRate\",$"},
- {"\"iterations\": %int,$", MR_Next},
- {"\"real_time\": %float,$", MR_Next},
- {"\"cpu_time\": %float,$", MR_Next},
- {"\"time_unit\": \"ns\",$", MR_Next},
- {"\"bar\": %float,$", MR_Next},
- {"\"foo\": %float$", MR_Next},
- {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_kAvgIterationsRate\",$"},
+ {"\"run_name\": \"BM_Counters_kAvgIterationsRate\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"bar\": %float,$", MR_Next},
+ {"\"foo\": %float$", MR_Next},
+ {"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_kAvgIterationsRate\",%csv_report,"
"%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
diff --git a/utils/google-benchmark/test/user_counters_thousands_test.cc b/utils/google-benchmark/test/user_counters_thousands_test.cc
new file mode 100644
index 000000000000..fa0ef9720470
--- /dev/null
+++ b/utils/google-benchmark/test/user_counters_thousands_test.cc
@@ -0,0 +1,161 @@
+
+#undef NDEBUG
+
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+// ========================================================================= //
+// ------------------------ Thousands Customisation ------------------------ //
+// ========================================================================= //
+
+void BM_Counters_Thousands(benchmark::State& state) {
+ for (auto _ : state) {
+ }
+ namespace bm = benchmark;
+ state.counters.insert({
+ {"t0_1000000DefaultBase",
+ bm::Counter(1000 * 1000, bm::Counter::kDefaults)},
+ {"t1_1000000Base1000", bm::Counter(1000 * 1000, bm::Counter::kDefaults,
+ benchmark::Counter::OneK::kIs1000)},
+ {"t2_1000000Base1024", bm::Counter(1000 * 1000, bm::Counter::kDefaults,
+ benchmark::Counter::OneK::kIs1024)},
+ {"t3_1048576Base1000", bm::Counter(1024 * 1024, bm::Counter::kDefaults,
+ benchmark::Counter::OneK::kIs1000)},
+ {"t4_1048576Base1024", bm::Counter(1024 * 1024, bm::Counter::kDefaults,
+ benchmark::Counter::OneK::kIs1024)},
+ });
+}
+BENCHMARK(BM_Counters_Thousands)->Repetitions(2);
+ADD_CASES(
+ TC_ConsoleOut,
+ {
+ {"^BM_Counters_Thousands/repeats:2 %console_report "
+ "t0_1000000DefaultBase=1000k "
+ "t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k "
+ "t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"},
+ {"^BM_Counters_Thousands/repeats:2 %console_report "
+ "t0_1000000DefaultBase=1000k "
+ "t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k "
+ "t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"},
+ {"^BM_Counters_Thousands/repeats:2_mean %console_report "
+ "t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k "
+ "t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k "
+ "t4_1048576Base1024=1024k$"},
+ {"^BM_Counters_Thousands/repeats:2_median %console_report "
+ "t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k "
+ "t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k "
+ "t4_1048576Base1024=1024k$"},
+ {"^BM_Counters_Thousands/repeats:2_stddev %console_time_only_report [ "
+ "]*2 t0_1000000DefaultBase=0 t1_1000000Base1000=0 "
+ "t2_1000000Base1024=0 t3_1048576Base1000=0 t4_1048576Base1024=0$"},
+ });
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Thousands/repeats:2\",$"},
+ {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next},
+ {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Thousands/repeats:2\",$"},
+ {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"iteration\",$", MR_Next},
+ {"\"iterations\": %int,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next},
+ {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Thousands/repeats:2_mean\",$"},
+ {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"mean\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next},
+ {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Thousands/repeats:2_median\",$"},
+ {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"median\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"t0_1000000DefaultBase\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t1_1000000Base1000\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t2_1000000Base1024\": 1\\.(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t3_1048576Base1000\": 1\\.048576(0)*e\\+(0)*6,$", MR_Next},
+ {"\"t4_1048576Base1024\": 1\\.048576(0)*e\\+(0)*6$", MR_Next},
+ {"}", MR_Next}});
+ADD_CASES(TC_JSONOut,
+ {{"\"name\": \"BM_Counters_Thousands/repeats:2_stddev\",$"},
+ {"\"run_name\": \"BM_Counters_Thousands/repeats:2\",$", MR_Next},
+ {"\"run_type\": \"aggregate\",$", MR_Next},
+ {"\"aggregate_name\": \"stddev\",$", MR_Next},
+ {"\"iterations\": 2,$", MR_Next},
+ {"\"real_time\": %float,$", MR_Next},
+ {"\"cpu_time\": %float,$", MR_Next},
+ {"\"time_unit\": \"ns\",$", MR_Next},
+ {"\"t0_1000000DefaultBase\": 0\\.(0)*e\\+(0)*,$", MR_Next},
+ {"\"t1_1000000Base1000\": 0\\.(0)*e\\+(0)*,$", MR_Next},
+ {"\"t2_1000000Base1024\": 0\\.(0)*e\\+(0)*,$", MR_Next},
+ {"\"t3_1048576Base1000\": 0\\.(0)*e\\+(0)*,$", MR_Next},
+ {"\"t4_1048576Base1024\": 0\\.(0)*e\\+(0)*$", MR_Next},
+ {"}", MR_Next}});
+
+ADD_CASES(
+ TC_CSVOut,
+ {{"^\"BM_Counters_Thousands/"
+ "repeats:2\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\.04858e\\+("
+ "0)*6,1\\.04858e\\+(0)*6$"},
+ {"^\"BM_Counters_Thousands/"
+ "repeats:2\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\.04858e\\+("
+ "0)*6,1\\.04858e\\+(0)*6$"},
+ {"^\"BM_Counters_Thousands/"
+ "repeats:2_mean\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\."
+ "04858e\\+(0)*6,1\\.04858e\\+(0)*6$"},
+ {"^\"BM_Counters_Thousands/"
+ "repeats:2_median\",%csv_report,1e\\+(0)*6,1e\\+(0)*6,1e\\+(0)*6,1\\."
+ "04858e\\+(0)*6,1\\.04858e\\+(0)*6$"},
+ {"^\"BM_Counters_Thousands/repeats:2_stddev\",%csv_report,0,0,0,0,0$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckThousands(Results const& e) {
+ if (e.name != "BM_Counters_Thousands/repeats:2")
+ return; // Do not check the aggregates!
+
+ // check that the values are within 0.01% of the expected values
+ CHECK_FLOAT_COUNTER_VALUE(e, "t0_1000000DefaultBase", EQ, 1000 * 1000,
+ 0.0001);
+ CHECK_FLOAT_COUNTER_VALUE(e, "t1_1000000Base1000", EQ, 1000 * 1000, 0.0001);
+ CHECK_FLOAT_COUNTER_VALUE(e, "t2_1000000Base1024", EQ, 1000 * 1000, 0.0001);
+ CHECK_FLOAT_COUNTER_VALUE(e, "t3_1048576Base1000", EQ, 1024 * 1024, 0.0001);
+ CHECK_FLOAT_COUNTER_VALUE(e, "t4_1048576Base1024", EQ, 1024 * 1024, 0.0001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_Thousands", &CheckThousands);
+
+// ========================================================================= //
+// --------------------------- TEST CASES END ------------------------------ //
+// ========================================================================= //
+
+int main(int argc, char* argv[]) { RunOutputTests(argc, argv); }
diff --git a/utils/google-benchmark/tools/compare.py b/utils/google-benchmark/tools/compare.py
index d27e24b34922..539ace6fb163 100755
--- a/utils/google-benchmark/tools/compare.py
+++ b/utils/google-benchmark/tools/compare.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
+import unittest
"""
compare.py - versatile benchmark output compare tool
"""
@@ -36,6 +37,17 @@ def create_parser():
parser = ArgumentParser(
description='versatile benchmark output compare tool')
+ parser.add_argument(
+ '-a',
+ '--display_aggregates_only',
+ dest='display_aggregates_only',
+ action="store_true",
+ help="If there are repetitions, by default, we display everything - the"
+ " actual runs, and the aggregates computed. Sometimes, it is "
+ "desirable to only view the aggregates. E.g. when there are a lot "
+ "of repetitions. Do note that only the display is affected. "
+ "Internally, all the actual runs are still used, e.g. for U test.")
+
utest = parser.add_argument_group()
utest.add_argument(
'--no-utest',
@@ -200,6 +212,9 @@ def main():
check_inputs(test_baseline, test_contender, benchmark_options)
+ if args.display_aggregates_only:
+ benchmark_options += ['--benchmark_display_aggregates_only=true']
+
options_baseline = []
options_contender = []
@@ -223,15 +238,13 @@ def main():
# Diff and output
output_lines = gbench.report.generate_difference_report(
- json1, json2, args.utest, args.utest_alpha)
+ json1, json2, args.display_aggregates_only,
+ args.utest, args.utest_alpha)
print(description)
for ln in output_lines:
print(ln)
-import unittest
-
-
class TestParser(unittest.TestCase):
def setUp(self):
self.parser = create_parser()
@@ -246,6 +259,7 @@ class TestParser(unittest.TestCase):
def test_benchmarks_basic(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
@@ -255,6 +269,7 @@ class TestParser(unittest.TestCase):
def test_benchmarks_basic_without_utest(self):
parsed = self.parser.parse_args(
['--no-utest', 'benchmarks', self.testInput0, self.testInput1])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertFalse(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.05)
self.assertEqual(parsed.mode, 'benchmarks')
@@ -262,9 +277,20 @@ class TestParser(unittest.TestCase):
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
+ def test_benchmarks_basic_display_aggregates_only(self):
+ parsed = self.parser.parse_args(
+ ['-a', 'benchmarks', self.testInput0, self.testInput1])
+ self.assertTrue(parsed.display_aggregates_only)
+ self.assertTrue(parsed.utest)
+ self.assertEqual(parsed.mode, 'benchmarks')
+ self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
+ self.assertEqual(parsed.test_contender[0].name, self.testInput1)
+ self.assertFalse(parsed.benchmark_options)
+
def test_benchmarks_basic_with_utest_alpha(self):
parsed = self.parser.parse_args(
['--alpha=0.314', 'benchmarks', self.testInput0, self.testInput1])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.314)
self.assertEqual(parsed.mode, 'benchmarks')
@@ -275,6 +301,7 @@ class TestParser(unittest.TestCase):
def test_benchmarks_basic_without_utest_with_utest_alpha(self):
parsed = self.parser.parse_args(
['--no-utest', '--alpha=0.314', 'benchmarks', self.testInput0, self.testInput1])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertFalse(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.314)
self.assertEqual(parsed.mode, 'benchmarks')
@@ -285,6 +312,7 @@ class TestParser(unittest.TestCase):
def test_benchmarks_with_remainder(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1, 'd'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
@@ -294,6 +322,7 @@ class TestParser(unittest.TestCase):
def test_benchmarks_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['benchmarks', self.testInput0, self.testInput1, '--', 'e'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarks')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
@@ -303,6 +332,7 @@ class TestParser(unittest.TestCase):
def test_filters_basic(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
@@ -313,6 +343,7 @@ class TestParser(unittest.TestCase):
def test_filters_with_remainder(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd', 'e'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
@@ -323,6 +354,7 @@ class TestParser(unittest.TestCase):
def test_filters_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['filters', self.testInput0, 'c', 'd', '--', 'f'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'filters')
self.assertEqual(parsed.test[0].name, self.testInput0)
@@ -333,6 +365,7 @@ class TestParser(unittest.TestCase):
def test_benchmarksfiltered_basic(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
@@ -344,6 +377,7 @@ class TestParser(unittest.TestCase):
def test_benchmarksfiltered_with_remainder(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', 'f'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
@@ -355,6 +389,7 @@ class TestParser(unittest.TestCase):
def test_benchmarksfiltered_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
['benchmarksfiltered', self.testInput0, 'c', self.testInput1, 'e', '--', 'g'])
+ self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, 'benchmarksfiltered')
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
diff --git a/utils/google-benchmark/tools/compare_bench.py b/utils/google-benchmark/tools/compare_bench.py
deleted file mode 100644
index 7bbf0d015747..000000000000
--- a/utils/google-benchmark/tools/compare_bench.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-"""
-compare_bench.py - Compare two benchmarks or their results and report the
- difference.
-"""
-import argparse
-from argparse import ArgumentParser
-import sys
-import gbench
-from gbench import util, report
-from gbench.util import *
-
-def check_inputs(in1, in2, flags):
- """
- Perform checking on the user provided inputs and diagnose any abnormalities
- """
- in1_kind, in1_err = classify_input_file(in1)
- in2_kind, in2_err = classify_input_file(in2)
- output_file = find_benchmark_flag('--benchmark_out=', flags)
- output_type = find_benchmark_flag('--benchmark_out_format=', flags)
- if in1_kind == IT_Executable and in2_kind == IT_Executable and output_file:
- print(("WARNING: '--benchmark_out=%s' will be passed to both "
- "benchmarks causing it to be overwritten") % output_file)
- if in1_kind == IT_JSON and in2_kind == IT_JSON and len(flags) > 0:
- print("WARNING: passing --benchmark flags has no effect since both "
- "inputs are JSON")
- if output_type is not None and output_type != 'json':
- print(("ERROR: passing '--benchmark_out_format=%s' to 'compare_bench.py`"
- " is not supported.") % output_type)
- sys.exit(1)
-
-
-def main():
- parser = ArgumentParser(
- description='compare the results of two benchmarks')
- parser.add_argument(
- 'test1', metavar='test1', type=str, nargs=1,
- help='A benchmark executable or JSON output file')
- parser.add_argument(
- 'test2', metavar='test2', type=str, nargs=1,
- help='A benchmark executable or JSON output file')
- parser.add_argument(
- 'benchmark_options', metavar='benchmark_options', nargs=argparse.REMAINDER,
- help='Arguments to pass when running benchmark executables'
- )
- args, unknown_args = parser.parse_known_args()
- # Parse the command line flags
- test1 = args.test1[0]
- test2 = args.test2[0]
- if unknown_args:
- # should never happen
- print("Unrecognized positional argument arguments: '%s'"
- % unknown_args)
- exit(1)
- benchmark_options = args.benchmark_options
- check_inputs(test1, test2, benchmark_options)
- # Run the benchmarks and report the results
- json1 = gbench.util.run_or_load_benchmark(test1, benchmark_options)
- json2 = gbench.util.run_or_load_benchmark(test2, benchmark_options)
- output_lines = gbench.report.generate_difference_report(json1, json2)
- print('Comparing %s to %s' % (test1, test2))
- for ln in output_lines:
- print(ln)
-
-
-if __name__ == '__main__':
- main()
diff --git a/utils/google-benchmark/tools/gbench/Inputs/test3_run0.json b/utils/google-benchmark/tools/gbench/Inputs/test3_run0.json
index ca793f3367e2..49f8b061437f 100644
--- a/utils/google-benchmark/tools/gbench/Inputs/test3_run0.json
+++ b/utils/google-benchmark/tools/gbench/Inputs/test3_run0.json
@@ -9,6 +9,7 @@
"benchmarks": [
{
"name": "BM_One",
+ "run_type": "aggregate",
"iterations": 1000,
"real_time": 10,
"cpu_time": 100,
@@ -25,15 +26,40 @@
"name": "BM_Two",
"iterations": 1000,
"real_time": 8,
+ "cpu_time": 86,
+ "time_unit": "ns"
+ },
+ {
+ "name": "short",
+ "run_type": "aggregate",
+ "iterations": 1000,
+ "real_time": 8,
"cpu_time": 80,
"time_unit": "ns"
},
{
"name": "short",
+ "run_type": "aggregate",
+ "iterations": 1000,
+ "real_time": 8,
+ "cpu_time": 77,
+ "time_unit": "ns"
+ },
+ {
+ "name": "medium",
+ "run_type": "iteration",
"iterations": 1000,
"real_time": 8,
"cpu_time": 80,
"time_unit": "ns"
+ },
+ {
+ "name": "medium",
+ "run_type": "iteration",
+ "iterations": 1000,
+ "real_time": 9,
+ "cpu_time": 82,
+ "time_unit": "ns"
}
]
}
diff --git a/utils/google-benchmark/tools/gbench/Inputs/test3_run1.json b/utils/google-benchmark/tools/gbench/Inputs/test3_run1.json
index e5cf50c7445e..acc5ba17aed1 100644
--- a/utils/google-benchmark/tools/gbench/Inputs/test3_run1.json
+++ b/utils/google-benchmark/tools/gbench/Inputs/test3_run1.json
@@ -16,6 +16,7 @@
},
{
"name": "BM_Two",
+ "run_type": "aggregate",
"iterations": 1000,
"real_time": 10,
"cpu_time": 89,
@@ -25,14 +26,39 @@
"name": "BM_Two",
"iterations": 1000,
"real_time": 7,
- "cpu_time": 70,
+ "cpu_time": 72,
"time_unit": "ns"
},
{
"name": "short",
+ "run_type": "aggregate",
"iterations": 1000,
- "real_time": 8,
- "cpu_time": 80,
+ "real_time": 7,
+ "cpu_time": 75,
+ "time_unit": "ns"
+ },
+ {
+ "name": "short",
+ "run_type": "aggregate",
+ "iterations": 762,
+ "real_time": 4.54,
+ "cpu_time": 66.6,
+ "time_unit": "ns"
+ },
+ {
+ "name": "short",
+ "run_type": "iteration",
+ "iterations": 1000,
+ "real_time": 800,
+ "cpu_time": 1,
+ "time_unit": "ns"
+ },
+ {
+ "name": "medium",
+ "run_type": "iteration",
+ "iterations": 1200,
+ "real_time": 5,
+ "cpu_time": 53,
"time_unit": "ns"
}
]
diff --git a/utils/google-benchmark/tools/gbench/report.py b/utils/google-benchmark/tools/gbench/report.py
index 4d03a5476776..5085b9319475 100644
--- a/utils/google-benchmark/tools/gbench/report.py
+++ b/utils/google-benchmark/tools/gbench/report.py
@@ -1,3 +1,4 @@
+import unittest
"""report.py - Utilities for reporting statistics about benchmark results
"""
import os
@@ -36,6 +37,7 @@ BC_UNDERLINE = BenchmarkColor('UNDERLINE', '\033[4m')
UTEST_MIN_REPETITIONS = 2
UTEST_OPTIMAL_REPETITIONS = 9 # Lowest reasonable number, More is better.
+UTEST_COL_NAME = "_pvalue"
def color_format(use_color, fmt_str, *args, **kwargs):
@@ -93,9 +95,103 @@ def filter_benchmark(json_orig, family, replacement=""):
return filtered
+def get_unique_benchmark_names(json):
+ """
+ While *keeping* the order, give all the unique 'names' used for benchmarks.
+ """
+ seen = set()
+ uniqued = [x['name'] for x in json['benchmarks']
+ if x['name'] not in seen and
+ (seen.add(x['name']) or True)]
+ return uniqued
+
+
+def intersect(list1, list2):
+ """
+ Given two lists, get a new list consisting of the elements only contained
+ in *both of the input lists*, while preserving the ordering.
+ """
+ return [x for x in list1 if x in list2]
+
+
+def partition_benchmarks(json1, json2):
+ """
+ While preserving the ordering, find benchmarks with the same names in
+ both of the inputs, and group them.
+ (i.e. partition/filter into groups with common name)
+ """
+ json1_unique_names = get_unique_benchmark_names(json1)
+ json2_unique_names = get_unique_benchmark_names(json2)
+ names = intersect(json1_unique_names, json2_unique_names)
+ partitions = []
+ for name in names:
+ # Pick the time unit from the first entry of the lhs benchmark.
+ time_unit = (x['time_unit']
+ for x in json1['benchmarks'] if x['name'] == name).next()
+ # Filter by name and time unit.
+ lhs = [x for x in json1['benchmarks'] if x['name'] == name and
+ x['time_unit'] == time_unit]
+ rhs = [x for x in json2['benchmarks'] if x['name'] == name and
+ x['time_unit'] == time_unit]
+ partitions.append([lhs, rhs])
+ return partitions
+
+
+def extract_field(partition, field_name):
+ # The count of elements may be different. We want *all* of them.
+ lhs = [x[field_name] for x in partition[0]]
+ rhs = [x[field_name] for x in partition[1]]
+ return [lhs, rhs]
+
+
+def print_utest(partition, utest_alpha, first_col_width, use_color=True):
+ timings_time = extract_field(partition, 'real_time')
+ timings_cpu = extract_field(partition, 'cpu_time')
+
+ min_rep_cnt = min(len(timings_time[0]),
+ len(timings_time[1]),
+ len(timings_cpu[0]),
+ len(timings_cpu[1]))
+
+ # Does *everything* has at least UTEST_MIN_REPETITIONS repetitions?
+ if min_rep_cnt < UTEST_MIN_REPETITIONS:
+ return []
+
+ def get_utest_color(pval):
+ return BC_FAIL if pval >= utest_alpha else BC_OKGREEN
+
+ time_pvalue = mannwhitneyu(
+ timings_time[0], timings_time[1], alternative='two-sided').pvalue
+ cpu_pvalue = mannwhitneyu(
+ timings_cpu[0], timings_cpu[1], alternative='two-sided').pvalue
+
+ dsc = "U Test, Repetitions: {} vs {}".format(
+ len(timings_cpu[0]), len(timings_cpu[1]))
+ dsc_color = BC_OKGREEN
+
+ if min_rep_cnt < UTEST_OPTIMAL_REPETITIONS:
+ dsc_color = BC_WARNING
+ dsc += ". WARNING: Results unreliable! {}+ repetitions recommended.".format(
+ UTEST_OPTIMAL_REPETITIONS)
+
+ special_str = "{}{:<{}s}{endc}{}{:16.4f}{endc}{}{:16.4f}{endc}{} {}"
+
+ last_name = partition[0][0]['name']
+ return [color_format(use_color,
+ special_str,
+ BC_HEADER,
+ "{}{}".format(last_name, UTEST_COL_NAME),
+ first_col_width,
+ get_utest_color(time_pvalue), time_pvalue,
+ get_utest_color(cpu_pvalue), cpu_pvalue,
+ dsc_color, dsc,
+ endc=BC_ENDC)]
+
+
def generate_difference_report(
json1,
json2,
+ display_aggregates_only=False,
utest=False,
utest_alpha=0.05,
use_color=True):
@@ -112,108 +208,95 @@ def generate_difference_report(
return b
return None
- utest_col_name = "_pvalue"
first_col_width = max(
first_col_width,
len('Benchmark'))
- first_col_width += len(utest_col_name)
+ first_col_width += len(UTEST_COL_NAME)
first_line = "{:<{}s}Time CPU Time Old Time New CPU Old CPU New".format(
'Benchmark', 12 + first_col_width)
output_strs = [first_line, '-' * len(first_line)]
- last_name = None
- timings_time = [[], []]
- timings_cpu = [[], []]
-
- gen = (bn for bn in json1['benchmarks']
- if 'real_time' in bn and 'cpu_time' in bn)
- for bn in gen:
- fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}"
- special_str = "{}{:<{}s}{endc}{}{:16.4f}{endc}{}{:16.4f}{endc}{} {}"
-
- if last_name is None:
- last_name = bn['name']
- if last_name != bn['name']:
- if ((len(timings_time[0]) >= UTEST_MIN_REPETITIONS) and
- (len(timings_time[1]) >= UTEST_MIN_REPETITIONS) and
- (len(timings_cpu[0]) >= UTEST_MIN_REPETITIONS) and
- (len(timings_cpu[1]) >= UTEST_MIN_REPETITIONS)):
- if utest:
- def get_utest_color(pval):
- if pval >= utest_alpha:
- return BC_FAIL
- else:
- return BC_OKGREEN
- time_pvalue = mannwhitneyu(
- timings_time[0], timings_time[1], alternative='two-sided').pvalue
- cpu_pvalue = mannwhitneyu(
- timings_cpu[0], timings_cpu[1], alternative='two-sided').pvalue
- dsc = "U Test, Repetitions: {}".format(len(timings_cpu[0]))
- dsc_color = BC_OKGREEN
- if len(timings_cpu[0]) < UTEST_OPTIMAL_REPETITIONS:
- dsc_color = BC_WARNING
- dsc += ". WARNING: Results unreliable! {}+ repetitions recommended.".format(
- UTEST_OPTIMAL_REPETITIONS)
- output_strs += [color_format(use_color,
- special_str,
- BC_HEADER,
- "{}{}".format(last_name,
- utest_col_name),
- first_col_width,
- get_utest_color(time_pvalue),
- time_pvalue,
- get_utest_color(cpu_pvalue),
- cpu_pvalue,
- dsc_color,
- dsc,
- endc=BC_ENDC)]
- last_name = bn['name']
- timings_time = [[], []]
- timings_cpu = [[], []]
-
- other_bench = find_test(bn['name'])
- if not other_bench:
- continue
-
- if bn['time_unit'] != other_bench['time_unit']:
- continue
+ partitions = partition_benchmarks(json1, json2)
+ for partition in partitions:
+ # Careful, we may have different repetition count.
+ for i in range(min(len(partition[0]), len(partition[1]))):
+ bn = partition[0][i]
+ other_bench = partition[1][i]
+
+ # *If* we were asked to only display aggregates,
+ # and if it is non-aggregate, then skip it.
+ if display_aggregates_only and 'run_type' in bn and 'run_type' in other_bench:
+ assert bn['run_type'] == other_bench['run_type']
+ if bn['run_type'] != 'aggregate':
+ continue
+
+ fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}"
+
+ def get_color(res):
+ if res > 0.05:
+ return BC_FAIL
+ elif res > -0.07:
+ return BC_WHITE
+ else:
+ return BC_CYAN
+
+ tres = calculate_change(bn['real_time'], other_bench['real_time'])
+ cpures = calculate_change(bn['cpu_time'], other_bench['cpu_time'])
+ output_strs += [color_format(use_color,
+ fmt_str,
+ BC_HEADER,
+ bn['name'],
+ first_col_width,
+ get_color(tres),
+ tres,
+ get_color(cpures),
+ cpures,
+ bn['real_time'],
+ other_bench['real_time'],
+ bn['cpu_time'],
+ other_bench['cpu_time'],
+ endc=BC_ENDC)]
+
+ # After processing the whole partition, if requested, do the U test.
+ if utest:
+ output_strs += print_utest(partition,
+ utest_alpha=utest_alpha,
+ first_col_width=first_col_width,
+ use_color=use_color)
- def get_color(res):
- if res > 0.05:
- return BC_FAIL
- elif res > -0.07:
- return BC_WHITE
- else:
- return BC_CYAN
-
- timings_time[0].append(bn['real_time'])
- timings_time[1].append(other_bench['real_time'])
- timings_cpu[0].append(bn['cpu_time'])
- timings_cpu[1].append(other_bench['cpu_time'])
-
- tres = calculate_change(timings_time[0][-1], timings_time[1][-1])
- cpures = calculate_change(timings_cpu[0][-1], timings_cpu[1][-1])
- output_strs += [color_format(use_color,
- fmt_str,
- BC_HEADER,
- bn['name'],
- first_col_width,
- get_color(tres),
- tres,
- get_color(cpures),
- cpures,
- timings_time[0][-1],
- timings_time[1][-1],
- timings_cpu[0][-1],
- timings_cpu[1][-1],
- endc=BC_ENDC)]
return output_strs
+
###############################################################################
# Unit tests
-import unittest
+class TestGetUniqueBenchmarkNames(unittest.TestCase):
+ def load_results(self):
+ import json
+ testInputs = os.path.join(
+ os.path.dirname(
+ os.path.realpath(__file__)),
+ 'Inputs')
+ testOutput = os.path.join(testInputs, 'test3_run0.json')
+ with open(testOutput, 'r') as f:
+ json = json.load(f)
+ return json
+
+ def test_basic(self):
+ expect_lines = [
+ 'BM_One',
+ 'BM_Two',
+ 'short', # These two are not sorted
+ 'medium', # These two are not sorted
+ ]
+ json = self.load_results()
+ output_lines = get_unique_benchmark_names(json)
+ print("\n")
+ print("\n".join(output_lines))
+ self.assertEqual(len(output_lines), len(expect_lines))
+ for i in range(0, len(output_lines)):
+ self.assertEqual(expect_lines[i], output_lines[i])
class TestReportDifference(unittest.TestCase):
@@ -259,7 +342,7 @@ class TestReportDifference(unittest.TestCase):
for i in range(0, len(output_lines)):
parts = [x for x in output_lines[i].split(' ') if x]
self.assertEqual(len(parts), 7)
- self.assertEqual(parts, expect_lines[i])
+ self.assertEqual(expect_lines[i], parts)
class TestReportDifferenceBetweenFamilies(unittest.TestCase):
@@ -293,7 +376,7 @@ class TestReportDifferenceBetweenFamilies(unittest.TestCase):
for i in range(0, len(output_lines)):
parts = [x for x in output_lines[i].split(' ') if x]
self.assertEqual(len(parts), 7)
- self.assertEqual(parts, expect_lines[i])
+ self.assertEqual(expect_lines[i], parts)
class TestReportDifferenceWithUTest(unittest.TestCase):
@@ -316,13 +399,15 @@ class TestReportDifferenceWithUTest(unittest.TestCase):
expect_lines = [
['BM_One', '-0.1000', '+0.1000', '10', '9', '100', '110'],
['BM_Two', '+0.1111', '-0.0111', '9', '10', '90', '89'],
- ['BM_Two', '+0.2500', '+0.1125', '8', '10', '80', '89'],
+ ['BM_Two', '-0.1250', '-0.1628', '8', '7', '86', '72'],
['BM_Two_pvalue',
- '0.2207',
- '0.6831',
+ '0.6985',
+ '0.6985',
'U',
'Test,',
'Repetitions:',
+ '2',
+ 'vs',
'2.',
'WARNING:',
'Results',
@@ -330,18 +415,103 @@ class TestReportDifferenceWithUTest(unittest.TestCase):
'9+',
'repetitions',
'recommended.'],
- ['short', '+0.0000', '+0.0000', '8', '8', '80', '80'],
+ ['short', '-0.1250', '-0.0625', '8', '7', '80', '75'],
+ ['short', '-0.4325', '-0.1351', '8', '5', '77', '67'],
+ ['short_pvalue',
+ '0.7671',
+ '0.1489',
+ 'U',
+ 'Test,',
+ 'Repetitions:',
+ '2',
+ 'vs',
+ '3.',
+ 'WARNING:',
+ 'Results',
+ 'unreliable!',
+ '9+',
+ 'repetitions',
+ 'recommended.'],
+ ['medium', '-0.3750', '-0.3375', '8', '5', '80', '53'],
+ ]
+ json1, json2 = self.load_results()
+ output_lines_with_header = generate_difference_report(
+ json1, json2, utest=True, utest_alpha=0.05, use_color=False)
+ output_lines = output_lines_with_header[2:]
+ print("\n")
+ print("\n".join(output_lines_with_header))
+ self.assertEqual(len(output_lines), len(expect_lines))
+ for i in range(0, len(output_lines)):
+ parts = [x for x in output_lines[i].split(' ') if x]
+ self.assertEqual(expect_lines[i], parts)
+
+
+class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly(
+ unittest.TestCase):
+ def load_results(self):
+ import json
+ testInputs = os.path.join(
+ os.path.dirname(
+ os.path.realpath(__file__)),
+ 'Inputs')
+ testOutput1 = os.path.join(testInputs, 'test3_run0.json')
+ testOutput2 = os.path.join(testInputs, 'test3_run1.json')
+ with open(testOutput1, 'r') as f:
+ json1 = json.load(f)
+ with open(testOutput2, 'r') as f:
+ json2 = json.load(f)
+ return json1, json2
+
+ def test_utest(self):
+ expect_lines = []
+ expect_lines = [
+ ['BM_One', '-0.1000', '+0.1000', '10', '9', '100', '110'],
+ ['BM_Two', '+0.1111', '-0.0111', '9', '10', '90', '89'],
+ ['BM_Two', '-0.1250', '-0.1628', '8', '7', '86', '72'],
+ ['BM_Two_pvalue',
+ '0.6985',
+ '0.6985',
+ 'U',
+ 'Test,',
+ 'Repetitions:',
+ '2',
+ 'vs',
+ '2.',
+ 'WARNING:',
+ 'Results',
+ 'unreliable!',
+ '9+',
+ 'repetitions',
+ 'recommended.'],
+ ['short', '-0.1250', '-0.0625', '8', '7', '80', '75'],
+ ['short', '-0.4325', '-0.1351', '8', '5', '77', '67'],
+ ['short_pvalue',
+ '0.7671',
+ '0.1489',
+ 'U',
+ 'Test,',
+ 'Repetitions:',
+ '2',
+ 'vs',
+ '3.',
+ 'WARNING:',
+ 'Results',
+ 'unreliable!',
+ '9+',
+ 'repetitions',
+ 'recommended.'],
]
json1, json2 = self.load_results()
output_lines_with_header = generate_difference_report(
- json1, json2, True, 0.05, use_color=False)
+ json1, json2, display_aggregates_only=True,
+ utest=True, utest_alpha=0.05, use_color=False)
output_lines = output_lines_with_header[2:]
print("\n")
print("\n".join(output_lines_with_header))
self.assertEqual(len(output_lines), len(expect_lines))
for i in range(0, len(output_lines)):
parts = [x for x in output_lines[i].split(' ') if x]
- self.assertEqual(parts, expect_lines[i])
+ self.assertEqual(expect_lines[i], parts)
if __name__ == '__main__':
diff --git a/utils/google-benchmark/tools/gbench/util.py b/utils/google-benchmark/tools/gbench/util.py
index 07c237727549..1f8e8e2c4796 100644
--- a/utils/google-benchmark/tools/gbench/util.py
+++ b/utils/google-benchmark/tools/gbench/util.py
@@ -7,11 +7,13 @@ import subprocess
import sys
# Input file type enumeration
-IT_Invalid = 0
-IT_JSON = 1
+IT_Invalid = 0
+IT_JSON = 1
IT_Executable = 2
_num_magic_bytes = 2 if sys.platform.startswith('win') else 4
+
+
def is_executable_file(filename):
"""
Return 'True' if 'filename' names a valid file which is likely
@@ -46,7 +48,7 @@ def is_json_file(filename):
with open(filename, 'r') as f:
json.load(f)
return True
- except:
+ except BaseException:
pass
return False
@@ -84,6 +86,7 @@ def check_input_file(filename):
sys.exit(1)
return ftype
+
def find_benchmark_flag(prefix, benchmark_flags):
"""
Search the specified list of flags for a flag matching `<prefix><arg>` and
@@ -97,6 +100,7 @@ def find_benchmark_flag(prefix, benchmark_flags):
result = f[len(prefix):]
return result
+
def remove_benchmark_flags(prefix, benchmark_flags):
"""
Return a new list containing the specified benchmark_flags except those
@@ -105,6 +109,7 @@ def remove_benchmark_flags(prefix, benchmark_flags):
assert prefix.startswith('--') and prefix.endswith('=')
return [f for f in benchmark_flags if not f.startswith(prefix)]
+
def load_benchmark_results(fname):
"""
Read benchmark output from a file and return the JSON object.
@@ -129,7 +134,7 @@ def run_benchmark(exe_name, benchmark_flags):
thandle, output_name = tempfile.mkstemp()
os.close(thandle)
benchmark_flags = list(benchmark_flags) + \
- ['--benchmark_out=%s' % output_name]
+ ['--benchmark_out=%s' % output_name]
cmd = [exe_name] + benchmark_flags
print("RUNNING: %s" % ' '.join(cmd))
@@ -156,4 +161,4 @@ def run_or_load_benchmark(filename, benchmark_flags):
elif ftype == IT_Executable:
return run_benchmark(filename, benchmark_flags)
else:
- assert False # This branch is unreachable \ No newline at end of file
+ assert False # This branch is unreachable
diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py
index 6542ceb6fb58..1aa52ddbbd41 100644
--- a/utils/libcxx/test/config.py
+++ b/utils/libcxx/test/config.py
@@ -133,7 +133,6 @@ class Configuration(object):
self.configure_cxx()
self.configure_triple()
self.configure_deployment()
- self.configure_availability()
self.configure_src_root()
self.configure_obj_root()
self.configure_cxx_stdlib_under_test()
@@ -307,16 +306,11 @@ class Configuration(object):
elif self.use_system_cxx_lib == 'false':
self.use_system_cxx_lib = False
elif self.use_system_cxx_lib:
- assert os.path.isdir(self.use_system_cxx_lib)
+ assert os.path.isdir(self.use_system_cxx_lib), "the specified use_system_cxx_lib parameter (%s) is not a valid directory" % self.use_system_cxx_lib
+ self.use_system_cxx_lib = os.path.abspath(self.use_system_cxx_lib)
self.lit_config.note(
"inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
- def configure_availability(self):
- # See http://llvm.org/docs/AvailabilityMarkup.html
- self.with_availability = self.get_lit_bool('with_availability', False)
- self.lit_config.note(
- "inferred with_availability as: %r" % self.with_availability)
-
def configure_cxx_stdlib_under_test(self):
self.cxx_stdlib_under_test = self.get_lit_conf(
'cxx_stdlib_under_test', 'libc++')
@@ -338,9 +332,6 @@ class Configuration(object):
def configure_use_clang_verify(self):
'''If set, run clang with -verify on failing tests.'''
- if self.with_availability:
- self.use_clang_verify = False
- return
self.use_clang_verify = self.get_lit_bool('use_clang_verify')
if self.use_clang_verify is None:
# NOTE: We do not test for the -verify flag directly because
@@ -416,12 +407,10 @@ class Configuration(object):
if self.use_deployment:
self.add_deployment_feature('with_system_cxx_lib')
- # Configure the availability markup checks features.
- if self.with_availability:
- self.config.available_features.add('availability_markup')
- self.add_deployment_feature('availability_markup')
-
- if self.use_system_cxx_lib or self.with_availability:
+ # Configure the availability feature. Availability is only enabled
+ # with libc++, because other standard libraries do not provide
+ # availability markup.
+ if self.use_deployment and self.cxx_stdlib_under_test == 'libc++':
self.config.available_features.add('availability')
self.add_deployment_feature('availability')
@@ -446,7 +435,7 @@ class Configuration(object):
# Run a compile test for the -fsized-deallocation flag. This is needed
# in test/std/language.support/support.dynamic/new.delete
if self.cxx.hasCompileFlag('-fsized-deallocation'):
- self.config.available_features.add('fsized-deallocation')
+ self.config.available_features.add('-fsized-deallocation')
if self.cxx.hasCompileFlag('-faligned-allocation'):
self.config.available_features.add('-faligned-allocation')
@@ -498,13 +487,7 @@ class Configuration(object):
self.config.available_features.add("objective-c++")
def configure_compile_flags(self):
- no_default_flags = self.get_lit_bool('no_default_flags', False)
- if not no_default_flags:
- self.configure_default_compile_flags()
- # This include is always needed so add so add it regardless of
- # 'no_default_flags'.
- support_path = os.path.join(self.libcxx_src_root, 'test/support')
- self.cxx.compile_flags += ['-I' + support_path]
+ self.configure_default_compile_flags()
# Configure extra flags
compile_flags_str = self.get_lit_conf('compile_flags', '')
self.cxx.compile_flags += shlex.split(compile_flags_str)
@@ -585,9 +568,10 @@ class Configuration(object):
self.cxx.flags += ['-arch', arch]
self.cxx.flags += ['-m' + name + '-version-min=' + version]
- # Disable availability unless explicitely requested
- if not self.with_availability:
- self.cxx.flags += ['-D_LIBCPP_DISABLE_AVAILABILITY']
+ # Add includes for support headers used in the tests.
+ support_path = os.path.join(self.libcxx_src_root, 'test/support')
+ self.cxx.compile_flags += ['-I' + support_path]
+
# FIXME(EricWF): variant_size.pass.cpp requires a slightly larger
# template depth with older Clang versions.
self.cxx.addFlagIfSupported('-ftemplate-depth=270')
@@ -677,7 +661,8 @@ class Configuration(object):
if feature_macros[m]:
define += '=%s' % (feature_macros[m])
self.cxx.compile_flags += [define]
- if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS':
+ if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS' or \
+ m == '_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT':
continue
if m == '_LIBCPP_ABI_VERSION':
self.config.available_features.add('libcpp-abi-version-v%s'
@@ -744,37 +729,33 @@ class Configuration(object):
def configure_link_flags(self):
- no_default_flags = self.get_lit_bool('no_default_flags', False)
- if not no_default_flags:
- # Configure library path
- self.configure_link_flags_cxx_library_path()
- self.configure_link_flags_abi_library_path()
-
- # Configure libraries
- if self.cxx_stdlib_under_test == 'libc++':
- self.cxx.link_flags += ['-nodefaultlibs']
- # FIXME: Handle MSVCRT as part of the ABI library handling.
- if self.is_windows:
- self.cxx.link_flags += ['-nostdlib']
- self.configure_link_flags_cxx_library()
- self.configure_link_flags_abi_library()
- self.configure_extra_library_flags()
- elif self.cxx_stdlib_under_test == 'libstdc++':
- enable_fs = self.get_lit_bool('enable_filesystem',
- default=False)
- if enable_fs:
- self.config.available_features.add('c++experimental')
- self.cxx.link_flags += ['-lstdc++fs']
- self.cxx.link_flags += ['-lm', '-pthread']
- elif self.cxx_stdlib_under_test == 'msvc':
- # FIXME: Correctly setup debug/release flags here.
- pass
- elif self.cxx_stdlib_under_test == 'cxx_default':
- self.cxx.link_flags += ['-pthread']
- else:
- self.lit_config.fatal(
- 'unsupported value for "use_stdlib_type": %s'
- % use_stdlib_type)
+ # Configure library path
+ self.configure_link_flags_cxx_library_path()
+ self.configure_link_flags_abi_library_path()
+
+ # Configure libraries
+ if self.cxx_stdlib_under_test == 'libc++':
+ self.cxx.link_flags += ['-nodefaultlibs']
+ # FIXME: Handle MSVCRT as part of the ABI library handling.
+ if self.is_windows:
+ self.cxx.link_flags += ['-nostdlib']
+ self.configure_link_flags_cxx_library()
+ self.configure_link_flags_abi_library()
+ self.configure_extra_library_flags()
+ elif self.cxx_stdlib_under_test == 'libstdc++':
+ enable_fs = self.get_lit_bool('enable_filesystem',
+ default=False)
+ if enable_fs:
+ self.config.available_features.add('c++experimental')
+ self.cxx.link_flags += ['-lstdc++fs']
+ self.cxx.link_flags += ['-lm', '-pthread']
+ elif self.cxx_stdlib_under_test == 'msvc':
+ # FIXME: Correctly setup debug/release flags here.
+ pass
+ elif self.cxx_stdlib_under_test == 'cxx_default':
+ self.cxx.link_flags += ['-pthread']
+ else:
+ self.lit_config.fatal('invalid stdlib under test')
link_flags_str = self.get_lit_conf('link_flags', '')
self.cxx.link_flags += shlex.split(link_flags_str)
@@ -930,9 +911,6 @@ class Configuration(object):
self.cxx.addWarningFlagIfSupported('-Wunused-variable')
self.cxx.addWarningFlagIfSupported('-Wunused-parameter')
self.cxx.addWarningFlagIfSupported('-Wunreachable-code')
- # FIXME: Enable the two warnings below.
- self.cxx.addWarningFlagIfSupported('-Wno-conversion')
- self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
std = self.get_lit_conf('std', None)
if std in ['c++98', 'c++03']:
# The '#define static_assert' provided by libc++ in C++03 mode
diff --git a/utils/libcxx/test/format.py b/utils/libcxx/test/format.py
index 74e3cc0aa308..6a334ac31cf4 100644
--- a/utils/libcxx/test/format.py
+++ b/utils/libcxx/test/format.py
@@ -188,7 +188,7 @@ class LibcxxTestFormat(object):
if rc != 0:
report = libcxx.util.makeReport(cmd, out, err, rc)
report += "Compilation failed unexpectedly!"
- return lit.Test.FAIL, report
+ return lit.Test.Result(lit.Test.FAIL, report)
# Run the test
local_cwd = os.path.dirname(source_path)
env = None
@@ -206,14 +206,14 @@ class LibcxxTestFormat(object):
cmd, out, err, rc = self.executor.run(exec_path, [exec_path],
local_cwd, data_files,
env)
+ report = "Compiled With: '%s'\n" % ' '.join(compile_cmd)
+ report += libcxx.util.makeReport(cmd, out, err, rc)
if rc == 0:
res = lit.Test.PASS if retry_count == 0 else lit.Test.FLAKYPASS
- return res, ''
+ return lit.Test.Result(res, report)
elif rc != 0 and retry_count + 1 == max_retry:
- report = libcxx.util.makeReport(cmd, out, err, rc)
- report = "Compiled With: %s\n%s" % (compile_cmd, report)
report += "Compiled test failed unexpectedly!"
- return lit.Test.FAIL, report
+ return lit.Test.Result(lit.Test.FAIL, report)
assert False # Unreachable
finally:
@@ -250,16 +250,15 @@ class LibcxxTestFormat(object):
#
# Therefore, we check if the test was expected to fail because of
# nodiscard before enabling it
- test_str = "ignoring return value of function declared with " \
- + "'nodiscard' attribute"
- if test_str in contents:
+ test_str_list = ['ignoring return value', 'nodiscard', 'NODISCARD']
+ if any(test_str in contents for test_str in test_str_list):
test_cxx.flags += ['-Werror=unused-result']
cmd, out, err, rc = test_cxx.compile(source_path, out=os.devnull)
expected_rc = 0 if use_verify else 1
+ report = libcxx.util.makeReport(cmd, out, err, rc)
if rc == expected_rc:
- return lit.Test.PASS, ''
+ return lit.Test.Result(lit.Test.PASS, report)
else:
- report = libcxx.util.makeReport(cmd, out, err, rc)
- report_msg = ('Expected compilation to fail!' if not use_verify else
- 'Expected compilation using verify to pass!')
- return lit.Test.FAIL, report + report_msg + '\n'
+ report += ('Expected compilation to fail!\n' if not use_verify else
+ 'Expected compilation using verify to pass!\n')
+ return lit.Test.Result(lit.Test.FAIL, report)
diff --git a/utils/libcxx/test/googlebenchmark.py b/utils/libcxx/test/googlebenchmark.py
new file mode 100644
index 000000000000..6fe731e8c91a
--- /dev/null
+++ b/utils/libcxx/test/googlebenchmark.py
@@ -0,0 +1,122 @@
+from __future__ import absolute_import
+import os
+import subprocess
+import sys
+
+import lit.Test
+import lit.TestRunner
+import lit.util
+from lit.formats.base import TestFormat
+
+kIsWindows = sys.platform in ['win32', 'cygwin']
+
+class GoogleBenchmark(TestFormat):
+ def __init__(self, test_sub_dirs, test_suffix, benchmark_args=[]):
+ self.benchmark_args = list(benchmark_args)
+ self.test_sub_dirs = os.path.normcase(str(test_sub_dirs)).split(';')
+
+ # On Windows, assume tests will also end in '.exe'.
+ exe_suffix = str(test_suffix)
+ if kIsWindows:
+ exe_suffix += '.exe'
+
+ # Also check for .py files for testing purposes.
+ self.test_suffixes = {exe_suffix, test_suffix + '.py'}
+
+ def getBenchmarkTests(self, path, litConfig, localConfig):
+ """getBenchmarkTests(path) - [name]
+
+ Return the tests available in gtest executable.
+
+ Args:
+ path: String path to a gtest executable
+ litConfig: LitConfig instance
+ localConfig: TestingConfig instance"""
+
+ # TODO: allow splitting tests according to the "benchmark family" so
+ # the output for a single family of tests all belongs to the same test
+ # target.
+ list_test_cmd = [path, '--benchmark_list_tests']
+ try:
+ output = subprocess.check_output(list_test_cmd,
+ env=localConfig.environment)
+ except subprocess.CalledProcessError as exc:
+ litConfig.warning(
+ "unable to discover google-benchmarks in %r: %s. Process output: %s"
+ % (path, sys.exc_info()[1], exc.output))
+ raise StopIteration
+
+ nested_tests = []
+ for ln in output.splitlines(False): # Don't keep newlines.
+ ln = lit.util.to_string(ln)
+ if not ln.strip():
+ continue
+
+ index = 0
+ while ln[index*2:index*2+2] == ' ':
+ index += 1
+ while len(nested_tests) > index:
+ nested_tests.pop()
+
+ ln = ln[index*2:]
+ if ln.endswith('.'):
+ nested_tests.append(ln)
+ elif any([name.startswith('DISABLED_')
+ for name in nested_tests + [ln]]):
+ # Gtest will internally skip these tests. No need to launch a
+ # child process for it.
+ continue
+ else:
+ yield ''.join(nested_tests) + ln
+
+ def getTestsInDirectory(self, testSuite, path_in_suite,
+ litConfig, localConfig):
+ source_path = testSuite.getSourcePath(path_in_suite)
+ for subdir in self.test_sub_dirs:
+ dir_path = os.path.join(source_path, subdir)
+ if not os.path.isdir(dir_path):
+ continue
+ for fn in lit.util.listdir_files(dir_path,
+ suffixes=self.test_suffixes):
+ # Discover the tests in this executable.
+ execpath = os.path.join(source_path, subdir, fn)
+ testnames = self.getBenchmarkTests(execpath, litConfig, localConfig)
+ for testname in testnames:
+ testPath = path_in_suite + (subdir, fn, testname)
+ yield lit.Test.Test(testSuite, testPath, localConfig,
+ file_path=execpath)
+
+ def execute(self, test, litConfig):
+ testPath,testName = os.path.split(test.getSourcePath())
+ while not os.path.exists(testPath):
+ # Handle GTest parametrized and typed tests, whose name includes
+ # some '/'s.
+ testPath, namePrefix = os.path.split(testPath)
+ testName = namePrefix + '/' + testName
+
+ cmd = [testPath, '--benchmark_filter=%s$' % testName ] + self.benchmark_args
+
+ if litConfig.noExecute:
+ return lit.Test.PASS, ''
+
+ try:
+ out, err, exitCode = lit.util.executeCommand(
+ cmd, env=test.config.environment,
+ timeout=litConfig.maxIndividualTestTime)
+ except lit.util.ExecuteCommandTimeoutException:
+ return (lit.Test.TIMEOUT,
+ 'Reached timeout of {} seconds'.format(
+ litConfig.maxIndividualTestTime)
+ )
+
+ if exitCode:
+ return lit.Test.FAIL, out + err
+
+ passing_test_line = testName
+ if passing_test_line not in out:
+ msg = ('Unable to find %r in google benchmark output:\n\n%s%s' %
+ (passing_test_line, out, err))
+ return lit.Test.UNRESOLVED, msg
+
+ return lit.Test.PASS, err + out
+
diff --git a/utils/libcxx/test/target_info.py b/utils/libcxx/test/target_info.py
index 0e93e11448bf..32bbb2e11504 100644
--- a/utils/libcxx/test/target_info.py
+++ b/utils/libcxx/test/target_info.py
@@ -15,6 +15,8 @@ import re
import subprocess
import sys
+from libcxx.util import executeCommand
+
class DefaultTargetInfo(object):
def __init__(self, full_config):
self.full_config = full_config
@@ -127,14 +129,13 @@ class DarwinLocalTI(DefaultTargetInfo):
cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
else:
cmd = ['xcrun', '--show-sdk-path']
- try:
- out = subprocess.check_output(cmd).strip()
- res = 0
- except OSError:
- res = -1
- if res == 0 and out:
- sdk_path = out
+ out, err, exit_code = executeCommand(cmd)
+ if exit_code != 0:
+ self.full_config.lit_config.warning("Could not determine macOS SDK path! stderr was " + err)
+ if exit_code == 0 and out:
+ sdk_path = out.strip()
self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
+ assert isinstance(sdk_path, str)
flags += ["-isysroot", sdk_path]
def add_cxx_link_flags(self, flags):
@@ -143,12 +144,12 @@ class DarwinLocalTI(DefaultTargetInfo):
def configure_env(self, env):
library_paths = []
# Configure the library path for libc++
- if self.full_config.use_system_cxx_lib:
+ if self.full_config.cxx_runtime_root:
+ library_paths += [self.full_config.cxx_runtime_root]
+ elif self.full_config.use_system_cxx_lib:
if (os.path.isdir(str(self.full_config.use_system_cxx_lib))):
library_paths += [self.full_config.use_system_cxx_lib]
- pass
- elif self.full_config.cxx_runtime_root:
- library_paths += [self.full_config.cxx_runtime_root]
+
# Configure the abi library path
if self.full_config.abi_library_root:
library_paths += [self.full_config.abi_library_root]
@@ -181,6 +182,18 @@ class FreeBSDLocalTI(DefaultTargetInfo):
flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
+class NetBSDLocalTI(DefaultTargetInfo):
+ def __init__(self, full_config):
+ super(NetBSDLocalTI, self).__init__(full_config)
+
+ def add_locale_features(self, features):
+ add_common_locales(features, self.full_config.lit_config)
+
+ def add_cxx_link_flags(self, flags):
+ flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lc++abi',
+ '-lunwind']
+
+
class LinuxLocalTI(DefaultTargetInfo):
def __init__(self, full_config):
super(LinuxLocalTI, self).__init__(full_config)
@@ -222,12 +235,17 @@ class LinuxLocalTI(DefaultTargetInfo):
self.full_config.config.available_features)
llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
+ # FIXME: Remove the need to link -lrt in all the tests, and instead
+ # limit it only to the filesystem tests. This ensures we don't cause an
+ # implicit dependency on librt except when filesystem is needed.
+ enable_fs = self.full_config.get_lit_bool('enable_filesystem',
+ default=False)
flags += ['-lm']
if not llvm_unwinder:
flags += ['-lgcc_s', '-lgcc']
if enable_threads:
flags += ['-lpthread']
- if not shared_libcxx:
+ if not shared_libcxx or enable_fs:
flags += ['-lrt']
flags += ['-lc']
if llvm_unwinder:
@@ -274,6 +292,7 @@ def make_target_info(full_config):
target_system = platform.system()
if target_system == 'Darwin': return DarwinLocalTI(full_config)
if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
+ if target_system == 'NetBSD': return NetBSDLocalTI(full_config)
if target_system == 'Linux': return LinuxLocalTI(full_config)
if target_system == 'Windows': return WindowsLocalTI(full_config)
return DefaultTargetInfo(full_config)
diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html
index 0bcd179de4c0..0af6352e9d6b 100644
--- a/www/cxx1y_status.html
+++ b/www/cxx1y_status.html
@@ -4,7 +4,7 @@
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <title>libc++ C++1Y Status</title>
+ <title>libc++ C++14 Status</title>
<link type="text/css" rel="stylesheet" href="menu.css">
<link type="text/css" rel="stylesheet" href="content.css">
</head>
@@ -32,12 +32,13 @@
<div id="content">
<!--*********************************************************************-->
- <h1>libc++ C++1Y Status</h1>
+ <h1>libc++ C++14 Status</h1>
<!--*********************************************************************-->
- <p>In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, known as "C++1Y" (probably to be C++14)</p>
+ <p>In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y".</p>
<p>The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol)</p>
- <p>This page shows the status of libc++; the status of clang's support of the language features is <a href="https://clang.llvm.org/cxx_status.html">here</a>.</p>
+ <p>In August 2014, this draft was approved by ISO as C++14</p>
+ <p>This page shows the status of libc++; the status of clang's support of the language features is <a href="https://clang.llvm.org/cxx_status.html#cxx14">here</a>.</p>
<p>The groups that have contributed papers:
<ul>
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
index 5f713ede981e..c2c6f7b02906 100644
--- a/www/cxx1z_status.html
+++ b/www/cxx1z_status.html
@@ -4,7 +4,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>libc++ C++1Z Status</title>
+ <title>libc++ C++17 Status</title>
<link type="text/css" rel="stylesheet" href="menu.css">
<link type="text/css" rel="stylesheet" href="content.css">
</head>
@@ -32,10 +32,10 @@
<div id="content">
<!--*********************************************************************-->
- <h1>libc++ C++1z Status</h1>
+ <h1>libc++ C++17 Status</h1>
<!--*********************************************************************-->
- <p>In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, known here as "C++1z" (probably to be C++17).</p>
+ <p>In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z".</p>
<p>In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17</p>
<p>This page shows the status of libc++; the status of clang's support of the language features is <a href="https://clang.llvm.org/cxx_status.html#cxx17">here</a>.</p>
@@ -101,7 +101,7 @@
<tr><td><a href="https://wg21.link/p0040r3">p0040r3</a></td><td>LWG</td><td>Extending memory management tools</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0063r3">p0063r3</a></td><td>LWG</td><td>C++17 should refer to C11 instead of C99</td><td>Oulu</td><td>Complete</td><td>7.0</td></tr>
<tr><td><a href="https://wg21.link/p0067r3">p0067r3</a></td><td>LWG</td><td>Elementary string conversions</td><td>Oulu</td><td>Now <a href="https://wg21.link/P0067R5">P0067R5</a></td><td>n/a</td></tr>
- <tr><td><a href="https://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td><i>Partially Done</i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td><i>Complete</i></td><td>8.0</td></tr>
<tr><td><a href="https://wg21.link/p0084r2">p0084r2</a></td><td>LWG</td><td>Emplace Return Type</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0088r3">p0088r3</a></td><td>LWG</td><td>Variant: a type-safe union for C++17</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0137r1">p0137r1</a></td><td>CWG</td><td>Core Issue 1776: Replacement of class objects containing reference members</td><td>Oulu</td><td>Complete</td><td>6.0</td></tr>
@@ -442,7 +442,7 @@
<tr><td><a href="https://wg21.link/LWG2777">2777</a></td><td>basic_string_view::copy should use char_traits::copy</td><td>Issaquah</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2778">2778</a></td><td>basic_string_view is missing constexpr</td><td>Issaquah</td><td>Complete</td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/LWG2260">2260</a></td><td>Missing requirement for Allocator::pointer</td><td>Kona</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2260">2260</a></td><td>Missing requirement for Allocator::pointer</td><td>Kona</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2676">2676</a></td><td>Provide filesystem::path overloads for File-based streams</td><td>Kona</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2768">2768</a></td><td>any_cast and move semantics</td><td>Kona</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2769">2769</a></td><td>Redundant const in the return type of any_cast(const any&amp;)</td><td>Kona</td><td>Complete</td></tr>
@@ -504,7 +504,7 @@
<!-- <tr><td></td><td></td><td></td><td></td></tr> -->
</table>
- <p>Last Updated: 22-May-2018</p>
+ <p>Last Updated: 3-Aug-2018</p>
</div>
</body>
</html>
diff --git a/www/cxx2a_status.html b/www/cxx2a_status.html
index fc69b296ee54..a5e87ec184bf 100644
--- a/www/cxx2a_status.html
+++ b/www/cxx2a_status.html
@@ -72,15 +72,15 @@
<tr><td><a href="https://wg21.link/P0767R1">P0767R1</a></td><td>CWG</td><td>Deprecate POD</td><td>Albuquerque</td><td>Complete</td><td>7.0</td></tr>
<tr><td><a href="https://wg21.link/P0768R1">P0768R1</a></td><td>CWG</td><td>Library Support for the Spaceship (Comparison) Operator</td><td>Albuquerque</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0777R1">P0777R1</a></td><td>LWG</td><td>Treating Unnecessary <tt>decay</tt></td><td>Albuquerque</td><td>Complete</td><td>7.0</td></tr>
- <tr><td><a href="https://wg21.link/P0122R7">P0122R7</a></td><td>LWG</td><td>&lt;span&gt;</td><td>Jacksonville</td><td><i>Complete</i></td><td>7.0</td></tr>
- <tr><td><a href="https://wg21.link/P0355R7">P0355R7</a></td><td>LWG</td><td>Extending chrono to Calendars and Time Zones</td><td>Jacksonville</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0122R7">P0122R7</a></td><td>LWG</td><td>&lt;span&gt;</td><td>Jacksonville</td><td>Complete</td><td>7.0</td></tr>
+ <tr><td><a href="https://wg21.link/P0355R7">P0355R7</a></td><td>LWG</td><td>Extending chrono to Calendars and Time Zones</td><td>Jacksonville</td><td><i>In progress</i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0551R3">P0551R3</a></td><td>LWG</td><td>Thou Shalt Not Specialize <tt>std</tt> Function Templates!</td><td>Jacksonville</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0753R2">P0753R2</a></td><td>LWG</td><td>Manipulators for C++ Synchronized Buffered Ostream</td><td>Jacksonville</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0754R2">P0754R2</a></td><td>LWG</td><td>&lt;version&gt;</td><td>Jacksonville</td><td>Complete</td><td>7.0</td></tr>
<tr><td><a href="https://wg21.link/P0809R0">P0809R0</a></td><td>LWG</td><td>Comparing Unordered Containers</td><td>Jacksonville</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0858R0">P0858R0</a></td><td>LWG</td><td>Constexpr iterator requirements</td><td>Jacksonville</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0905R1">P0905R1</a></td><td>CWG</td><td>Symmetry for spaceship</td><td>Jacksonville</td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P0966R1">P0966R1</a></td><td>LWG</td><td><tt>string::reserve</tt> Should Not Shrink</td><td>Jacksonville</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0966R1">P0966R1</a></td><td>LWG</td><td><tt>string::reserve</tt> Should Not Shrink</td><td>Jacksonville</td><td>Complete</td><td>8.0</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0019R8">P0019R8</a></td><td>LWG</td><td>Atomic Ref</td><td>Rapperswil</td><td></td><td></td></tr>
@@ -89,7 +89,7 @@
<tr><td><a href="https://wg21.link/P0476R2">P0476R2</a></td><td>LWG</td><td>Bit-casting object representations</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0528R3">P0528R3</a></td><td>CWG</td><td>The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0542R5">P0542R5</a></td><td>CWG</td><td>Support for contract based programming in C++</td><td>Rapperswil</td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P0556R3">P0556R3</a></td><td>LWG</td><td>Integral power-of-2 operations</td><td>Rapperswil</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0556R3">P0556R3</a></td><td>LWG</td><td>Integral power-of-2 operations</td><td>Rapperswil</td><td><i>In Progress</i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0619R4">P0619R4</a></td><td>LWG</td><td>Reviewing Deprecated Facilities of C++17 for C++20</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0646R1">P0646R1</a></td><td>LWG</td><td>Improving the Return Value of Erase-Like Algorithms</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0722R3">P0722R3</a></td><td>CWG</td><td>Efficient sized delete for variable sized classes</td><td>Rapperswil</td><td></td><td></td></tr>
@@ -98,15 +98,46 @@
<tr><td><a href="https://wg21.link/P0769R2">P0769R2</a></td><td>LWG</td><td>Add shift to &lt;algorithm&gt;</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0788R3">P0788R3</a></td><td>LWG</td><td>Standard Library Specification in a Concepts and Contracts World</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0879R0">P0879R0</a></td><td>LWG</td><td>Constexpr for swap and swap related functions Also resolves LWG issue 2800.</td><td>Rapperswil</td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P0887R1">P0887R1</a></td><td>LWG</td><td>The identity metafunction</td><td>Rapperswil</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0887R1">P0887R1</a></td><td>LWG</td><td>The identity metafunction</td><td>Rapperswil</td><td>Complete</td><td>8.0</td></tr>
<tr><td><a href="https://wg21.link/P0892R2">P0892R2</a></td><td>CWG</td><td>explicit(bool)</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0898R3">P0898R3</a></td><td>LWG</td><td>Standard Library Concepts</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0935R0">P0935R0</a></td><td>LWG</td><td>Eradicating unnecessarily explicit default constructors from the standard library</td><td>Rapperswil</td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P0941R2">P0941R2</a></td><td>CWG</td><td>Integrating feature-test macros into the C++ WD</td><td>Rapperswil</td><td></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P1023R0">P1023R0</a></td><td>LWG</td><td>constexpr comparison operators for std::array</td><td>Rapperswil</td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0941R2">P0941R2</a></td><td>CWG</td><td>Integrating feature-test macros into the C++ WD</td><td>Rapperswil</td><td><i>In progress</i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1023R0">P1023R0</a></td><td>LWG</td><td>constexpr comparison operators for std::array</td><td>Rapperswil</td><td>Complete</td><td>8.0</td></tr>
<tr><td><a href="https://wg21.link/P1025R1">P1025R1</a></td><td>CWG</td><td>Update The Reference To The Unicode Standard</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1120R0">P1120R0</a></td><td>CWG</td><td>Consistency improvements for &lt;=&gt; and other comparison operators</td><td>Rapperswil</td><td></td><td></td></tr>
+ <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0318R1">P0318R1</a></td><td>LWG</td><td>unwrap_ref_decay and unwrap_reference</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P0356R5">P0356R5</a></td><td>LWG</td><td>Simplified partial function application</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0357R3">P0357R3</a></td><td>LWG</td><td>reference_wrapper for incomplete types</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0482R6">P0482R6</a></td><td>CWG</td><td>char8_t: A type for UTF-8 characters and strings</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0487R1">P0487R1</a></td><td>LWG</td><td>Fixing operator&gt;&gt;(basic_istream&amp;, CharT*) (LWG 2499)</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P0591R4">P0591R4</a></td><td>LWG</td><td>Utility functions to implement uses-allocator construction</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0595R2">P0595R2</a></td><td>CWG</td><td>P0595R2 std::is_constant_evaluated()</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0602R4">P0602R4</a></td><td>LWG</td><td>variant and optional should propagate copy/move triviality</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P0608R3">P0608R3</a></td><td>LWG</td><td>A sane variant converting constructor</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0655R1">P0655R1</a></td><td>LWG</td><td>visit&lt;R&gt;: Explicit Return Type for visit</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0771R1">P0771R1</a></td><td>LWG</td><td>std::function move constructor should be noexcept</td><td>San Diego</td><td>Complete</td><td>6.0</td></tr>
+ <tr><td><a href="https://wg21.link/P0896R4">P0896R4</a></td><td>LWG</td><td>The One Ranges Proposal</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0899R1">P0899R1</a></td><td>LWG</td><td>P0899R1 - LWG 3016 is not a defect</td><td>San Diego</td><td><i>Nothing to do</i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0919R3">P0919R3</a></td><td>LWG</td><td>Heterogeneous lookup for unordered containers</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P0972R0">P0972R0</a></td><td>LWG</td><td>&lt;chrono&gt; <tt>zero()</tt>, <tt>min()</tt>, and <tt>max()</tt> should be noexcept</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P1006R1">P1006R1</a></td><td>LWG</td><td>Constexpr in std::pointer_traits</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P1007R3">P1007R3</a></td><td>LWG</td><td><tt>std::assume_aligned</tt></td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1020R1">P1020R1</a></td><td>LWG</td><td>Smart pointer creation with default initialization</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1032R1">P1032R1</a></td><td>LWG</td><td>Misc constexpr bits</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1085R2">P1085R2</a></td><td>LWG</td><td>Should Span be Regular?</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P1123R0">P1123R0</a></td><td>LWG</td><td>Editorial Guidance for merging P0019r8 and P0528r3</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1148R0">P1148R0</a></td><td>LWG</td><td>Cleaning up Clause 20</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1165R1">P1165R1</a></td><td>LWG</td><td>Make stateful allocator propagation more consistent for <tt>operator+(basic_string)</tt></td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1209R0">P1209R0</a></td><td>LWG</td><td>Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr>
+ <tr><td><a href="https://wg21.link/P1210R0">P1210R0</a></td><td>LWG</td><td>Completing the Rebase of Library Fundamentals, Version 3, Working Draft</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1236R1">P1236R1</a></td><td>CWG</td><td>Alternative Wording for P0907R4 Signed Integers are Two's Complement</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1248R1">P1248R1</a></td><td>LWG</td><td>Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1285R0">P1285R0</a></td><td>LWG</td><td>Improving Completeness Requirements for Type Traits</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1353R0">P1353R0</a></td><td>CWG</td><td>Missing feature test macros</td><td>San Diego</td><td><i> </i></td><td></td></tr>
+
<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> -->
</table>
@@ -148,8 +179,8 @@
<tr><td><a href="https://wg21.link/LWG2948">2948</a></td><td>unique_ptr does not define operator<< for stream output</td><td>Albuquerque</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2950">2950</a></td><td>std::byte operations are misspecified</td><td>Albuquerque</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG2952">2952</a></td><td>iterator_traits should work for pointers to cv T</td><td>Albuquerque</td><td>Complete</td></tr>
- <tr><td><a href="https://wg21.link/LWG2953">2953</a></td><td>LWG 2853 should apply to deque::erase too</td><td>Albuquerque</td><td></td></tr>
- <tr><td><a href="https://wg21.link/LWG2958">2958</a></td><td>Moves improperly defined as deleted</td><td>Albuquerque</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2953">2953</a></td><td>LWG 2853 should apply to deque::erase too</td><td>Albuquerque</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2958">2958</a></td><td>Moves improperly defined as deleted</td><td>Albuquerque</td><td><I>We already do this</I></td></tr>
<tr><td><a href="https://wg21.link/LWG2964">2964</a></td><td>Apparently redundant requirement for dynamic_pointer_cast</td><td>Albuquerque</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG2965">2965</a></td><td>Non-existing path::native_string() in filesystem_error::what() specification</td><td>Albuquerque</td><td>Nothing to do</td></tr>
<tr><td><a href="https://wg21.link/LWG2972">2972</a></td><td>What is is_trivially_destructible_v&lt;int&gt;?</td><td>Albuquerque</td><td>Complete</td></tr>
@@ -187,7 +218,7 @@
<tr><td><a href="https://wg21.link/LWG3013">3013</a></td><td><tt>(recursive_)directory_iterator</tt> construction and traversal should not be <tt>noexcept</tt></td><td>Jacksonville</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3014">3014</a></td><td>More <tt>noexcept</tt> issues with filesystem operations</td><td>Jacksonville</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3015">3015</a></td><td><tt>copy_options::<i>unspecified</i></tt> underspecified</td><td>Jacksonville</td><td><i>Nothing to do</i></td></tr>
- <tr><td><a href="https://wg21.link/LWG3017">3017</a></td><td><tt>list splice</tt> functions should use <tt>addressof</tt></td><td>Jacksonville</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3017">3017</a></td><td><tt>list splice</tt> functions should use <tt>addressof</tt></td><td>Jacksonville</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3020">3020</a></td><td>[networking.ts] Remove spurious nested <tt>value_type</tt> buffer sequence requirement</td><td>Jacksonville</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG3026">3026</a></td><td><tt>filesystem::weakly_canonical</tt> still defined in terms of <tt>canonical(p, base)</tt></td><td>Jacksonville</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3030">3030</a></td><td>Who shall meet the requirements of <tt>try_lock</tt>?</td><td>Jacksonville</td><td><i>Nothing to do</i></td></tr>
@@ -216,13 +247,51 @@
<tr><td><a href="https://wg21.link/LWG3083">3083</a></td><td>What should ios::iword(-1) do?</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
<tr><td><a href="https://wg21.link/LWG3094">3094</a></td><td>[time.duration.io]p4 makes surprising claims about encoding</td><td>Rapperswil</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG3100">3100</a></td><td>Unnecessary and confusing "empty span" wording</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
- <tr><td><a href="https://wg21.link/LWG3102">3102</a></td><td>Clarify span iterator and const_iterator behavior</td><td>Rapperswil</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3102">3102</a></td><td>Clarify span iterator and const_iterator behavior</td><td>Rapperswil</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3104">3104</a></td><td>Fixing duration division</td><td>Rapperswil</td><td>Complete</td></tr>
+ <tr><td></td><td></td><td></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2183">2183</a></td><td>Muddled allocator requirements for <tt>match_results</tt> constructors</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2184">2184</a></td><td>Muddled allocator requirements for <tt>match_results</tt> assignments</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2412">2412</a></td><td><tt>promise::set_value()</tt> and <tt>promise::get_future()</tt> should not race</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2499">2499</a></td><td><tt>operator&gt;&gt;(basic_istream&amp;, CharT*)</tt> makes it hard to avoid buffer overflows</td><td>San Diego</td><td>Resolved by P0487R1</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2682">2682</a></td><td><code>filesystem::copy()</code> won't create a symlink to a directory</td><td>San Diego</td><td>Nothing to do</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2697">2697</a></td><td>[concurr.ts] Behavior of <tt>future/shared_future</tt> unwrapping constructor when given an invalid <tt>future</tt></td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2797">2797</a></td><td>Trait precondition violations</td><td>San Diego</td><td>Resolved by 1285R0</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2936">2936</a></td><td>Path comparison is defined in terms of the generic format</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2943">2943</a></td><td>Problematic specification of the wide version of <tt>basic_filebuf::open</tt></td><td>San Diego</td><td>Nothing to do</td></tr>
+ <tr><td><a href="https://wg21.link/LWG2960">2960</a></td><td>[fund.ts.v3] <tt>nonesuch</tt> is insufficiently useless</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2995">2995</a></td><td><tt>basic_stringbuf</tt> default constructor forbids it from using SSO capacity</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG2996">2996</a></td><td>Missing rvalue overloads for <tt>shared_ptr</tt> operations</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3008">3008</a></td><td><tt>make_shared</tt> (sub)object destruction semantics are not specified</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3022">3022</a></td><td><tt>is_convertible&lt;derived*, base*&gt;</tt> may lead to ODR</td><td>San Diego</td><td>Resolved by 1285R0</td></tr>
+ <tr><td><a href="https://wg21.link/LWG3025">3025</a></td><td>Map-like container deduction guides should use <tt>pair&lt;Key, T&gt;</tt>, not <tt>pair&lt;const Key, T&gt;</tt></td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3031">3031</a></td><td>Algorithms and predicates with non-const reference arguments</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3037">3037</a></td><td><tt>polymorphic_allocator</tt> and incomplete types</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3038">3038</a></td><td><tt>polymorphic_allocator::allocate</tt> should not allow integer overflow to create vulnerabilities</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3054">3054</a></td><td><tt>uninitialized_copy</tt> appears to not be able to meet its exception-safety guarantee</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3065">3065</a></td><td>LWG 2989 missed that all <tt>path</tt>'s other operators should be hidden friends as well</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG3096">3096</a></td><td><tt>path::lexically_relative</tt> is confused by trailing slashes</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG3116">3116</a></td><td><tt><i>OUTERMOST_ALLOC_TRAITS</i></tt> needs <tt>remove_reference_t</tt></td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3122">3122</a></td><td><tt>__cpp_lib_chrono_udls</tt> was accidentally dropped</td><td>San Diego</td><td><i>We've already made the update; but we don't support all the test macros. When we do, this will be closed</i></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3127">3127</a></td><td><tt>basic_osyncstream::rdbuf</tt> needs a <tt>const_cast</tt></td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3128">3128</a></td><td><tt>strstream::rdbuf</tt> needs a <tt>const_cast</tt></td><td>San Diego</td><td><i>Nothing to do</i></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3129">3129</a></td><td><tt>regex_token_iterator</tt> constructor uses wrong pointer arithmetic</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3130">3130</a></td><td>&sect;[input.output] needs many <tt>addressof</tt></td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3131">3131</a></td><td><tt>addressof</tt> all the things</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3132">3132</a></td><td>Library needs to ban macros named <tt>expects</tt> or <tt>ensures</tt></td><td>San Diego</td><td><i>Nothing to do</i></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3134">3134</a></td><td>[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961</td><td>San Diego</td><td>Resolved by P1210R0</td></tr>
+ <tr><td><a href="https://wg21.link/LWG3137">3137</a></td><td>Header for <tt>__cpp_lib_to_chars</tt></td><td>San Diego</td><td><i>We've already made the update; but we don't support all the test macros. When we do, this will be closed</i></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td>Complete</td></tr>
+ <tr><td><a href="https://wg21.link/LWG3147">3147</a></td><td>Definitions of "likely" and "unlikely" are likely to cause problems</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3148">3148</a></td><td><tt>&lt;concepts&gt;</tt> should be freestanding</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3153">3153</a></td><td><tt>Common</tt> and <tt>common_type</tt> have too little in common</td><td>San Diego</td><td></td></tr>
+ <tr><td><a href="https://wg21.link/LWG3154">3154</a></td><td><tt>Common</tt> and <tt>CommonReference</tt> have a common defect</td><td>San Diego</td><td></td></tr>
+
<!-- <tr><td></td><td></td><td></td><td></td></tr> -->
</table>
- <p>Last Updated: 23-Jul-2018</p>
+ <p>Last Updated: 28-Nov-2018</p>
</div>
</body>
</html>
diff --git a/www/index.html b/www/index.html
index 8f9ae510f8f5..3724b8b43624 100644
--- a/www/index.html
+++ b/www/index.html
@@ -22,8 +22,9 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="https://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="https://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="https://libcxxabi.llvm.org/">libc++abi</a>
+ <a href="https://lists.llvm.org/mailman/listinfo/libcxx-dev">libcxx-dev</a>
+ <a href="https://lists.llvm.org/mailman/listinfo/libcxx-commits">libcxx-commits</a>
<a href="https://bugs.llvm.org/">Bug Reports</a>
<a href="https://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="https://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
@@ -35,8 +36,8 @@
<h1>"libc++" C++ Standard Library</h1>
<!--*********************************************************************-->
- <p>libc++ is a new implementation of the C++ standard library, targeting
- C++11.</p>
+ <p>libc++ is an implementation of the C++ standard library, targeting
+ C++11, C++14 and above.</p>
<p>All of the code in libc++ is <a
href="https://llvm.org/docs/DeveloperPolicy.html#license">dual licensed</a>
@@ -114,9 +115,8 @@
<!--=====================================================================-->
<p>
- libc++ is known to work on the following platforms, using g++-4.2 and
- clang (lack of C++11 language support disables some functionality). Note
- that functionality provided by &lt;atomic&gt; is only functional with
+ libc++ is known to work on the following platforms, using g++ and
+ clang. Note that functionality provided by &lt;atomic&gt; is only functional with
clang.
</p>
@@ -126,6 +126,8 @@
<li>FreeBSD 10+ i386</li>
<li>FreeBSD 10+ x86_64</li>
<li>FreeBSD 10+ ARM</li>
+ <li>Linux i386</li>
+ <li>Linux x86_64</li>
</ul>
<!--=====================================================================-->
@@ -198,7 +200,7 @@
</p>
<p>Send discussions to the
- <a href="https://lists.llvm.org/mailman/listinfo/cfe-dev">clang mailing list</a>.</p>
+ <a href="https://lists.llvm.org/mailman/listinfo/libcxx-dev">libc++ mailing list</a>.</p>
<!--=====================================================================-->
<h2>Bug reports and patches</h2>
@@ -207,14 +209,14 @@
<p>
If you think you've found a bug in libc++, please report it using
the <a href="https://bugs.llvm.org/">LLVM Bugzilla</a>. If you're not sure, you
- can post a message to the <a href="https://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
- mailing list or on IRC. Please include "libc++" in your subject.
+ can post a message to the <a href="https://lists.llvm.org/mailman/listinfo/libcxx-dev">libcxx-dev</a>
+ mailing list or on IRC.
</p>
<p>
If you want to contribute a patch to libc++, the best place for that is
<a href="https://llvm.org/docs/Phabricator.html">Phabricator</a>. Please
- include [libc++] in the subject and add cfe-commits as a subscriber.
+ add libcxx-commits as a subscriber.
</p>
<!--=====================================================================-->
diff --git a/www/upcoming_meeting.html b/www/upcoming_meeting.html
index 500bfb4c7016..0b88d1c66c6b 100644
--- a/www/upcoming_meeting.html
+++ b/www/upcoming_meeting.html
@@ -35,7 +35,7 @@
<h1>libc++ Upcoming Meeting Status</h1>
<!--*********************************************************************-->
- <p>This is a temporary page; please check the c++1z status <a href="cxx1z_status.html">here</a></p>
+ <p>This is a temporary page; please check the c++2a status <a href="cxx2a_status.html">here</a></p>
<p>This page shows the status of the papers and issues that are expected to be adopted in the next WG21 Meeting.</p>
<p>The groups that have contributed papers:
@@ -47,77 +47,104 @@
</p>
<h3>Paper Status</h3>
- <table id="papers" border="1">
- <tr><th>Paper #</th><th>Paper Name</th><th>Meeting</th><th>Status</th></tr>
- <tr><td><a href="https://wg21.link/P0805R1">P0805R1</a></td><td>Comparing Containers</td><td>Jacksonville</td><td><i>Patch Ready: <a href="https://reviews.llvm.org/D43773">D43773</a></i></td></tr>
-<!--
- <tr><td><a href="https://wg21.link/LWGn3346">3346</a></td><td>LWG</td><td>Terminology for Container Element Requirements - Rev 1</td><td>Kona</td><td>Complete</td><td>3.4</td></tr>
--->
-<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> -->
- </table>
+ <table border="1">
+ <tr><th>Paper #</th><th>Group</th><th>Paper Name</th><th>Meeting</th><th>Status</th></tr>
+ <tr><td><a href="https://wg21.link/P0487R0">P0487R0</a></td><td>LWG</td><td>Fixing operator&gt;&gt; (basic_istream&amp;, CharT*) (LWG 2499)</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="https://wg21.link/P0602R3">P0602R3</a></td><td>LWG</td><td>variant and optional should propagate copy/move triviality</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="https://wg21.link/P0655R0">P0655R0</a></td><td>LWG</td><td>visit&lt;R&gt;: Explicit Return Type for visit</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="https://wg21.link/P0972R0">P0972R0</a></td><td>LWG</td><td>&lt;chrono&gt; zero(), min(), and max() should be noexcept</td><td>San Diego</td><td>See <a href="https://reviews.llvm.org/D53828">D53828</a></td></tr>
+ <tr><td><a href="https://wg21.link/P1004R0">P1004R0</a></td><td>LWG</td><td>Making std::vector constexpr</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="https://wg21.link/P1006R0">P1006R0</a></td><td>LWG</td><td>Constexpr in std::pointer_traits</td><td>San Diego</td><td>See <a href="https://reviews.llvm.org/D53867">D53867</a></td></tr>
+ <tr><td><a href="https://wg21.link/P1032R0">P1032R0</a></td><td>LWG</td><td>Misc constexpr bits</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="http://wiki.edg.com/pub/LWGBatavia2018/LibraryWorkingGroup/D1148R0a.pdf">D1148</a></td><td>LWG</td><td>Cleaning up Clause 20</td><td>San Diego</td><td><i> </i></td></tr>
+ <tr><td><a href="http://wiki.edg.com/pub/LWGBatavia2018/LibraryWorkingGroup/D1163R0V2.pdf">D1163</a></td><td>LWG</td><td>Explicitly Implicifying explicit Constructors</td><td>San Diego</td><td><i> </i></td></tr>
+ </table>
+
<h3>Library Working group Issues Status</h3>
<table id="issues" border="1">
<tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr>
-<tr><td><a href="https://wg21.link/LWG2139">2139</a></td><td>What is a user-defined type?</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG2970">2970</a></td><td>Return type of std::visit misspecified</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3058">3058</a></td><td>Parallel adjacent_difference shouldn't require creating temporaries</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3062">3062</a></td><td>Unnecessary decay_t in is_execution_policy_v should be remove_cvref_t</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3067">3067</a></td><td>recursive_directory_iterator::pop must invalidate</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
-<tr><td><a href="https://wg21.link/LWG3071">3071</a></td><td>[networking.ts] read_until still refers to "input sequence"</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
-<tr><td><a href="https://wg21.link/LWG3074">3074</a></td><td>Non-member functions for valarray should only deduce from the valarray</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3076">3076</a></td><td>basic_string CTAD ambiguity</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3079">3079</a></td><td>LWG 2935 forgot to fix the existing_p overloads of create_directory</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3080">3080</a></td><td>Floating point from_chars pattern specification breaks round-tripping</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3083">3083</a></td><td>What should ios::iword(-1) do?</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
-<tr><td><a href="https://wg21.link/LWG3094">3094</a></td><td>[time.duration.io]p4 makes surprising claims about encoding</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3100">3100</a></td><td>Unnecessary and confusing "empty span" wording</td><td>Rapperswil</td><td><i>Nothing to do</i></td></tr>
-<tr><td><a href="https://wg21.link/LWG3102">3102</a></td><td>Clarify span iterator and const_iterator behavior</td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3104">3104</a></td><td>Fixing duration division</td><td>Rapperswil</td><td>Complete</td></tr>
+<tr><td><a href="https://wg21.link/LWG2183">2183</a></td><td>Muddled allocator requirements for <tt>match_results</tt> constructors</td><td>San Diego</td><td>Complete</td></tr>
+<tr><td><a href="https://wg21.link/LWG2184">2184</a></td><td>Muddled allocator requirements for <tt>match_results</tt> assignments</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2412">2412</a></td><td><tt>promise::set_value()</tt> and <tt>promise::get_future()</tt> should not race</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2682">2682</a></td><td><code>filesystem::copy()</code> won't create a symlink to a directory</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2697">2697</a></td><td>[concurr.ts] Behavior of <tt>future/shared_future</tt> unwrapping constructor when given an invalid <tt>future</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2936">2936</a></td><td>Path comparison is defined in terms of the generic format</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2943">2943</a></td><td>Problematic specification of the wide version of <tt>basic_filebuf::open</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2960">2960</a></td><td>[fund.ts.v3] <tt>nonesuch</tt> is insufficiently useless</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG2995">2995</a></td><td><tt>basic_stringbuf</tt> default constructor forbids it from using SSO capacity</td><td>San Diego</td><td><i>We know how to do this</i></td></tr>
+<tr><td><a href="https://wg21.link/LWG2996">2996</a></td><td>Missing rvalue overloads for <tt>shared_ptr</tt> operations</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3008">3008</a></td><td><tt>make_shared</tt> (sub)object destruction semantics are not specified</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3025">3025</a></td><td>Map-like container deduction guides should use <tt>pair&lt;Key, T&gt;</tt>, not <tt>pair&lt;const Key, T&gt;</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3031">3031</a></td><td>Algorithms and predicates with non-const reference arguments</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3037">3037</a></td><td><tt>polymorphic_allocator</tt> and incomplete types</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3038">3038</a></td><td><tt>polymorphic_allocator::allocate</tt> should not allow integer overflow to create vulnerabilities</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3054">3054</a></td><td><tt>uninitialized_copy</tt> appears to not be able to meet its exception-safety guarantee</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3065">3065</a></td><td>LWG 2989 missed that all <tt>path</tt>'s other operators should be hidden friends as well</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3096">3096</a></td><td><tt>path::lexically_relative</tt> is confused by trailing slashes</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3116">3116</a></td><td><tt><i>OUTERMOST_ALLOC_TRAITS</i></tt> needs <tt>remove_reference_t</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3122">3122</a></td><td><tt>__cpp_lib_chrono_udls</tt> was accidentally dropped</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3127">3127</a></td><td><tt>basic_osyncstream::rdbuf</tt> needs a <tt>const_cast</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3128">3128</a></td><td><tt>strstream::rdbuf</tt> needs a <tt>const_cast</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3129">3129</a></td><td><tt>regex_token_iterator</tt> constructor uses wrong pointer arithmetic</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3130">3130</a></td><td>&sect;[input.output] needs many <tt>addressof</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3131">3131</a></td><td><tt>addressof</tt> all the things</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3132">3132</a></td><td>Library needs to ban macros named <tt>expects</tt> or <tt>ensures</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3134">3134</a></td><td>[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3137">3137</a></td><td>Header for <tt>__cpp_lib_to_chars</tt></td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3147">3147</a></td><td>Definitions of "likely" and "unlikely" are likely to cause problems</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3148">3148</a></td><td><tt>&lt;concepts&gt;</tt> should be freestanding</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3153">3153</a></td><td><tt>Common</tt> and <tt>common_type</tt> have too little in common</td><td>San Diego</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3154">3154</a></td><td><tt>Common</tt> and <tt>CommonReference</tt> have a common defect</td><td>San Diego</td><td></td></tr>
</table>
<h3>Issues to "Review"</h3>
<table border="1">
<tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr>
-<tr><td><a href="https://wg21.link/LWG2412">2412</a></td><td><tt>promise::set_value()</tt> and <tt>promise::get_future()</tt> should not race</td><td>Rapperswil</td><td>Complete</td></tr>
-<tr><td><a href="https://wg21.link/LWG2682">2682</a></td><td><code>filesystem::copy()</code> won't create a symlink to a directory</td><td>Rapperswil</td><td>Complete</td></tr>
-<tr><td><a href="https://wg21.link/LWG2697">2697</a></td><td>[concurr.ts] Behavior of <tt>future/shared_future</tt> unwrapping constructor when given an invalid <tt>future</tt></td><td>Rapperswil</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG2708">2708</a></td><td><tt>recursive_directory_iterator::recursion_pending()</tt> is incorrectly specified</td><td>Rapperswil</td><td>Complete</td></tr>
-<tr><td><a href="https://wg21.link/LWG2936">2936</a></td><td>Path comparison is defined in terms of the generic format</td><td>Rapperswil</td><td></td></tr>
</table>
<h3>Comments about the issues</h3>
<ul>
-<li>2139 - I think that this is just wording cleanup.</li>
-<li>2970 - I think that we already do this - checking with Michael.</li>
-<li>3058 - We don't do the parallel algos yet</li>
-<li>3062 - This should be very easy.</li>
-<li>3067 - Adding restrictions; no code changes needed.</li>
-<li>3071 - This is just wording cleanup.</li>
-<li>3074 - Large change, that looks straightforward.</li>
-<li>3076 - </li>
-<li>3079 - Eric? </li>
-<li>3080 - We don't have a from_chars implementation yet.</li>
-<li>3083 - This is just wording cleanup.</li>
-<li>3094 - We haven't implemented Howard's date library yet.</li>
-<li>3100 - This is just wording cleanup.</li>
-<li>3102 - This should be just adding tests.</li>
-<li>3104 - We already do this.</li>
-</ul>
-
-<h3>Comments about the "Review" issues</h3>
-<ul>
-<li> 2412 - I think we do this already</li>
-<li> 2682 - We already to this </li>
-<li> 2697 - No concurrency TS implementation yet</li>
-<li> 2708 - We already do this </li>
-<li> 2936 - Eric - don't we do this already?</li>
+<li>2183 - We're missing tests for match_results (copy ctor, move ctor). I committed them in r344988.</li>
+<li>2184 - We're missing tests for match_results (copy assign, move assing). I wrote them. Unfortunately, the move-assign test fails.</li>
+<li>2412 - </li>
+<li>2682 - Eric? </li>
+<li>2697 - </li>
+<li>2936 - </li>
+<li>2943 - Eric? I suspect that this is no change for us.</li>
+<li>2960 - </li>
+<li>2995 - We used to do this. Reverting r320604 and r321124 will get us back there.</li>
+<li>2996 - </li>
+<li>3008 - </li>
+<li>3025 - </li>
+<li>3031 - Marshall says: I don't think we have to do anything for this issue. Maybe some tests; maybe a static_assert.</li>
+<li>3037 - Marshall says: We don't have std::polymorphic_allocator yet.</li>
+<li>3038 - Marshall says: We don't have std::polymorphic_allocator yet.</li>
+<li>3054 - Marshall says: We already do this; may need to update some tests.</li>
+<li>3065 - </li>
+<li>3096 - Eric? </li>
+<li>3116 - </li>
+<li>3122 - Marshall says I have updated the comments in &lt;version&gt; and in the tests.</li>
+<li>3127 - Marshall says: We don't have basic_osyncstream yet.</li>
+<li>3128 - </li>
+<li>3129 - Marshall says: This is an easy change; I think this is more wording cleanup than anything. I will prepare a patch</li>
+<li>3130 - </li>
+<li>3131 - Only changes 11 & 12 affect libc++. </li>
+<li>3132 - Marshall says: I don't think we have to do anything for this issue</li>
+<li>3134 - Marshall says: I don't think we have to do anything for this issue</li>
+<li>3137 - Marshall says I have updated the comments in &lt;version&gt; and in the tests.</li>
+<li>3145 - Eric? </li>
+<li>3147 - Marshall - I don't think we have to do anything for this issue</li>
+<li>3148 - </li>
+<li>3153 - </li>
+<li>3154 - </li>
</ul>
-<p>Last Updated: 10-May-2018</p>
+<p>Last Updated: 29-Oct-2018</p>
</div>
</body>
</html>