summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2019-04-15 11:42:08 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-04-15 11:42:08 -0700
commitd2122edb2ec42a8bfa867e216c8544539a74b27f (patch)
treea4455fea62dcd64bbd974d2fc5604bc0ac6180f2
parent044186190ed5a6a2f7a25c5fff971201135f5946 (diff)
parent49e2509752a07c9464b3b7152dca8edba8f94545 (diff)
downloadexternal_libcxx-ndk-r20-beta3.tar.gz
external_libcxx-ndk-r20-beta3.tar.bz2
external_libcxx-ndk-r20-beta3.zip
Merge remote-tracking branch 'aosp/ndk' into update-from-masterndk-r20-beta3ndk-r20
am: 49e2509752 Change-Id: I9d3e298c71f4e9f3addc45a0c74686c3a2307632
-rw-r--r--CMakeLists.txt74
-rw-r--r--benchmarks/CMakeLists.txt76
-rw-r--r--benchmarks/algorithms.bench.cpp332
-rw-r--r--benchmarks/algorithms.partition_point.bench.cpp124
-rw-r--r--benchmarks/function.bench.cpp2
-rw-r--r--benchmarks/lit.cfg.py23
-rw-r--r--benchmarks/lit.site.cfg.py.in10
-rw-r--r--benchmarks/string.bench.cpp12
-rw-r--r--cmake/Modules/HandleCompilerRT.cmake3
-rw-r--r--cmake/Modules/HandleLibcxxFlags.cmake23
-rw-r--r--docs/BuildingLibcxx.rst22
-rw-r--r--docs/DesignDocs/AvailabilityMarkup.rst49
-rw-r--r--docs/ReleaseNotes.rst12
-rw-r--r--docs/TestingLibcxx.rst11
-rw-r--r--docs/UsingLibcxx.rst6
-rw-r--r--fuzzing/fuzzing.cpp829
-rw-r--r--include/CMakeLists.txt1
-rw-r--r--include/__config82
-rw-r--r--include/__hash_table60
-rw-r--r--include/__string97
-rw-r--r--include/__tree30
-rw-r--r--include/__tuple18
-rw-r--r--include/algorithm1
-rw-r--r--include/any6
-rw-r--r--include/array4
-rw-r--r--include/bitset2
-rw-r--r--include/chrono263
-rw-r--r--include/deque27
-rw-r--r--include/exception4
-rw-r--r--include/experimental/any18
-rw-r--r--include/experimental/chrono18
-rw-r--r--include/experimental/dynarray305
-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/filesystem92
-rw-r--r--include/forward_list17
-rw-r--r--include/fstream1
-rw-r--r--include/functional838
-rw-r--r--include/iosfwd17
-rw-r--r--include/istream60
-rw-r--r--include/iterator19
-rw-r--r--include/limits2
-rw-r--r--include/list19
-rw-r--r--include/locale5
-rw-r--r--include/map59
-rw-r--r--include/memory80
-rw-r--r--include/module.modulemap4
-rw-r--r--include/new35
-rw-r--r--include/optional11
-rw-r--r--include/ostream3
-rw-r--r--include/regex4
-rw-r--r--include/set62
-rw-r--r--include/shared_mutex15
-rw-r--r--include/span44
-rw-r--r--include/streambuf2
-rw-r--r--include/string189
-rw-r--r--include/string_view24
-rw-r--r--include/tuple28
-rw-r--r--include/type_traits3
-rw-r--r--include/typeinfo8
-rw-r--r--include/unordered_map28
-rw-r--r--include/unordered_set23
-rw-r--r--include/utility63
-rw-r--r--include/variant23
-rw-r--r--include/vector17
-rw-r--r--include/version9
-rw-r--r--lib/CMakeLists.txt128
-rw-r--r--lib/abi/CHANGELOG.TXT68
-rw-r--r--lib/abi/x86_64-apple-darwin.v1.abilist18
-rw-r--r--lib/abi/x86_64-apple-darwin.v2.abilist18
-rw-r--r--lib/abi/x86_64-unknown-linux-gnu.v1.abilist22
-rw-r--r--lib/libc++abi2.exp10
-rw-r--r--src/filesystem/filesystem_common.h31
-rw-r--r--src/filesystem/operations.cpp106
-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/half_positive.pass.cpp7
-rw-r--r--test/libcxx/containers/associative/non_const_comparator.fail.cpp3
-rw-r--r--test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp26
-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/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp22
-rw-r--r--test/libcxx/double_include.sh.cpp1
-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.cpp (renamed from test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp)12
-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/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp37
-rw-r--r--test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp25
-rw-r--r--test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp8
-rw-r--r--test/libcxx/memory/aligned_allocation_macro.pass.cpp18
-rw-r--r--test/libcxx/min_max_macros.sh.cpp2
-rw-r--r--test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp63
-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/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/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/atomics/atomics.lockfree/isalwayslockfree.pass.cpp4
-rw-r--r--test/std/containers/Emplaceable.h2
-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.erasure/erase_if.pass.cpp79
-rw-r--r--test/std/containers/associative/map/map.modifiers/merge.pass.cpp1
-rw-r--r--test/std/containers/associative/multimap/multimap.erasure/erase_if.pass.cpp89
-rw-r--r--test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp1
-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/merge.pass.cpp1
-rw-r--r--test/std/containers/associative/multiset/multiset.erasure/erase_if.pass.cpp78
-rw-r--r--test/std/containers/associative/set/merge.pass.cpp1
-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/map_allocator_requirement_test_templates.h8
-rw-r--r--test/std/containers/sequences/array/array.data/data.pass.cpp10
-rw-r--r--test/std/containers/sequences/array/array.data/data_const.pass.cpp5
-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.cpp9
-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/erase_iter.pass.cpp2
-rw-r--r--test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp2
-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/resize_size_value.pass.cpp1
-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/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.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.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/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/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/index.pass.cpp1
-rw-r--r--test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp6
-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/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/merge.pass.cpp6
-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/merge.pass.cpp6
-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/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/merge.pass.cpp6
-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.cpp2
-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/math_h.pass.cpp39
-rw-r--r--test/std/depr/depr.c.headers/uchar_h.pass.cpp1
-rw-r--r--test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/overflow.pass.cpp8
-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.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/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/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp37
-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.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp35
-rw-r--r--test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp37
-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.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.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/any.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp14
-rw-r--r--test/std/language.support/support.limits/support.limits.general/bit.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/charconv.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/chrono.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/cmath.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/compare.version.pass.cpp32
-rw-r--r--test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/cstddef.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/deque.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/exception.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp3
-rw-r--r--test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp14
-rw-r--r--test/std/language.support/support.limits/support.limits.general/forward_list.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/functional.version.pass.cpp3
-rw-r--r--test/std/language.support/support.limits/support.limits.general/iomanip.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/istream.version.pass.cpp43
-rw-r--r--test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/limits.version.pass.cpp43
-rw-r--r--test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/locale.version.pass.cpp43
-rw-r--r--test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/memory_resource.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/mutex.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/new.version.pass.cpp3
-rw-r--r--test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/optional.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/ostream.version.pass.cpp43
-rw-r--r--test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/scoped_allocator.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/set.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/shared_mutex.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp23
-rw-r--r--test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp3
-rw-r--r--test/std/language.support/support.limits/support.limits.general/unordered_map.version.pass.cpp13
-rw-r--r--test/std/language.support/support.limits/support.limits.general/unordered_set.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/utility.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/variant.version.pass.cpp1
-rw-r--r--test/std/language.support/support.limits/support.limits.general/vector.version.pass.cpp12
-rw-r--r--test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp21
-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.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/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.results/re.results.const/copy.pass.cpp2
-rw-r--r--test/std/re/re.results/re.results.const/copy_assign.pass.cpp2
-rw-r--r--test/std/re/re.results/re.results.const/move_assign.pass.cpp2
-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/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.cpp (renamed from test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp)22
-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/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.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.cpp9
-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/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.cpp13
-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.cpp4
-rw-r--r--test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp4
-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/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_to.pass.cpp17
-rw-r--r--test/std/utilities/meta/meta.type.synop/endian.pass.cpp1
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp3
-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/time/date.time/ctime.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/euclidian.h5
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/ctor.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/increment.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.members/plus_minus_equal.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/comparisons.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/minus.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/plus.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/streaming.pass.cpp20
-rw-r--r--test/std/utilities/time/time.cal/time.cal.day/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.last/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/day.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.members/ok.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/comparisons.pass.cpp26
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/time.cal.md.nonmembers/streaming.pass.cpp8
-rw-r--r--test/std/utilities/time/time.cal/time.cal.md/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/comparisons.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/streaming.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/decrement.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/increment.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.members/plus_minus_equal.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/comparisons.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp8
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/plus.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/streaming.pass.cpp22
-rw-r--r--test/std/utilities/time/time.cal/time.cal.month/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/comparisons.pass.cpp20
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/streaming.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwd/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.members/ctor.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/comparisons.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/streaming.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.mwdlast/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_day.pass.cpp10
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_day_last.pass.cpp12
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_weekday.pass.cpp10
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/month_weekday_last.pass.cpp14
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_day.pass.cpp21
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_day_last.pass.cpp28
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday.pass.cpp14
-rw-r--r--test/std/utilities/time/time.cal/time.cal.operators/year_month_weekday_last.pass.cpp17
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.members/ctor.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/comparisons.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/streaming.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdidx/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/comparisons.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/streaming.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.wdlast/types.pass.cpp2
-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.cpp4
-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.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/increment.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/operator[].pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.members/plus_minus_equal.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/comparisons.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/plus.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/streaming.pass.cpp16
-rw-r--r--test/std/utilities/time/time.cal/time.cal.weekday/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/decrement.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/increment.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus.pass.cpp3
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.members/plus_minus_equal.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/comparisons.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/minus.pass.cpp8
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/streaming.pass.cpp20
-rw-r--r--test/std/utilities/time/time.cal/time.cal.year/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/ctor.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_year.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/comparisons.pass.cpp24
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp12
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp8
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/streaming.pass.cpp18
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ym/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.local_days.pass.cpp53
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.sys_days.pass.cpp54
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ctor.year_month_day_last.pass.cpp48
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp31
-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.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_year.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/comparisons.pass.cpp30
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/minus.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/streaming.pass.cpp18
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymd/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ctor.pass.cpp5
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/day.pass.cpp32
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/month_day_last.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/ok.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_local_days.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/op_sys_days.pass.cpp39
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp3
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_year.pass.cpp3
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/year.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/comparisons.pass.cpp19
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp5
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp11
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/streaming.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.local_days.pass.cpp67
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.pass.cpp3
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.sys_days.pass.cpp69
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp41
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/index.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/month.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ok.pass.cpp1
-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.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_year.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/weekday_indexed.pass.cpp1
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/year.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/comparisons.pass.cpp15
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp9
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/plus.pass.cpp7
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/streaming.pass.cpp18
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwd/types.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/ctor.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_local_days.pass.cpp38
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/op_sys_days.pass.cpp55
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp2
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/comparisons.pass.cpp14
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/minus.pass.cpp6
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/plus.pass.cpp8
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/streaming.pass.cpp4
-rw-r--r--test/std/utilities/time/time.cal/time.cal.ymwdlast/types.pass.cpp2
-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.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.cpp2
-rw-r--r--test/std/utilities/time/time.point/time.point.arithmetic/op_-=.pass.cpp2
-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/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.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.cpp20
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp20
-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/min_allocator.h54
-rw-r--r--test/support/nasty_macros.hpp3
-rw-r--r--test/support/poisoned_hash_helper.hpp2
-rw-r--r--test/support/test_comparisons.h4
-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
-rwxr-xr-xutils/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.py101
-rw-r--r--utils/libcxx/test/format.py2
-rw-r--r--utils/libcxx/test/googlebenchmark.py122
-rw-r--r--utils/libcxx/test/target_info.py36
-rw-r--r--www/cxx2a_status.html73
817 files changed, 15282 insertions, 6529 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ea6571125..a57e36fdd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -83,6 +83,11 @@ option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
# Benchmark options -----------------------------------------------------------
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++")
@@ -278,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
#===============================================================================
@@ -643,38 +651,48 @@ 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 =====================================================
@@ -756,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/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
index 40489cabc..3823b87b3 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)
@@ -112,6 +149,9 @@ macro(add_benchmark_test name source_file)
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"
@@ -119,13 +159,17 @@ 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++fs -lc++experimental)
endif()
@@ -141,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()
#==============================================================================
@@ -158,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/algorithms.bench.cpp b/benchmarks/algorithms.bench.cpp
index ab0e81b0c..eee8a4da2 100644
--- a/benchmarks/algorithms.bench.cpp
+++ b/benchmarks/algorithms.bench.cpp
@@ -1,126 +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;
-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::sort(Copy.begin(), Copy.end());
+ });
+ }
-BENCHMARK_CAPTURE(BM_Sort, sorted_descending_uint32,
- getReverseSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+ bool skip() const { return Order() == ::Order::Heap; }
-BENCHMARK_CAPTURE(BM_Sort, single_element_uint32,
- getDuplicateIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+ std::string name() const {
+ return "BM_Sort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_Sort, pipe_organ_uint32,
- getPipeOrganIntegerInputs<uint32_t>)->Arg(TestNumInputs);
+template <class ValueType, class Order>
+struct StableSort {
+ size_t Quantity;
-BENCHMARK_CAPTURE(BM_Sort, random_strings,
- getRandomStringInputs)->Arg(TestNumInputs);
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::stable_sort(Copy.begin(), Copy.end());
+ });
+ }
-BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_strings,
- getSortedStringInputs)->Arg(TestNumInputs);
+ bool skip() const { return Order() == ::Order::Heap; }
-BENCHMARK_CAPTURE(BM_Sort, sorted_descending_strings,
- getReverseSortedStringInputs)->Arg(TestNumInputs);
+ std::string name() const {
+ return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_Sort, single_element_strings,
- getDuplicateStringInputs)->Arg(TestNumInputs);
+template <class ValueType, class Order>
+struct MakeHeap {
+ size_t Quantity;
-template <typename GenInputs, typename Alg>
-void do_binary_search_benchmark(benchmark::State& st, GenInputs gen, Alg alg)
-{
- using ValueType = typename decltype(gen(0))::value_type;
- auto in = gen(st.range(0));
- std::sort(in.begin(), in.end());
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
+ std::make_heap(Copy.begin(), Copy.end());
+ });
+ }
- const auto every_10_percentile = [&]() -> std::vector<ValueType*> {
- size_t step = in.size() / 10;
+ std::string name() const {
+ return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
- if (step == 0) {
- st.SkipWithError("Input doesn't contain enough elements");
- return {};
- }
+template <class ValueType>
+struct SortHeap {
+ size_t Quantity;
- std::vector<ValueType*> res;
- for (size_t i = 0; i < in.size(); i += step)
- res.push_back(&in[i]);
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order::Heap, false,
+ [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
+ }
- return res;
- }();
+ std::string name() const {
+ return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
- for (auto _ : st)
- {
- for (auto* test : every_10_percentile)
- benchmark::DoNotOptimize(alg(in.begin(), in.end(), *test));
- }
-}
+template <class ValueType, class Order>
+struct MakeThenSortHeap {
+ size_t Quantity;
-template <typename GenInputs>
-void BM_LowerBound(benchmark::State& st, GenInputs gen)
-{
- do_binary_search_benchmark(st, gen, [](auto f, auto l, const auto& v) {
- return std::lower_bound(f, l, v);
+ 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());
});
-}
+ }
+
+ 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_CAPTURE(BM_LowerBound, random_int32, getRandomIntegerInputs<int32_t>)
- ->Arg(TestNumInputs) // Small int32_t vector
- ->Arg(TestNumInputs * TestNumInputs); // Big int32_t vector
+ 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; }
-BENCHMARK_CAPTURE(BM_LowerBound, random_int64, getRandomIntegerInputs<int64_t>)
- ->Arg(TestNumInputs); // Small int64_t vector. Should also represent pointers.
+ std::string name() const {
+ return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_LowerBound, random_strings, getRandomStringInputs)
- ->Arg(TestNumInputs); // Small string vector. What happens if the comparison is not very cheap.
+template <class ValueType>
+struct PopHeap {
+ size_t Quantity;
-template <typename GenInputs>
-void BM_EqualRange(benchmark::State& st, GenInputs gen)
-{
- do_binary_search_benchmark(st, gen, [](auto f, auto l, const auto& v) {
- return std::equal_range(f, l, v);
+ 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);
+ }
});
-}
+ }
-BENCHMARK_CAPTURE(BM_EqualRange, random_int32, getRandomIntegerInputs<int32_t>)
- ->Arg(TestNumInputs) // Small int32_t vector
- ->Arg(TestNumInputs * TestNumInputs); // Big int32_t vector
+ std::string name() const {
+ return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
-BENCHMARK_CAPTURE(BM_EqualRange, random_int64, getRandomIntegerInputs<int64_t>)
- ->Arg(TestNumInputs); // Small int64_t vector. Should also represent pointers.
+} // namespace
-BENCHMARK_CAPTURE(BM_EqualRange, random_strings, getRandomStringInputs)
- ->Arg(TestNumInputs); // Small string vector. What happens if the comparison is not very cheap.
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
-BENCHMARK_MAIN();
+ 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 000000000..00a3bb272
--- /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
index 484d1973f..4f0e1fd80 100644
--- a/benchmarks/function.bench.cpp
+++ b/benchmarks/function.bench.cpp
@@ -48,7 +48,7 @@ struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
struct S {
int function() const { return 0; }
- int field;
+ int field = 0;
};
int FunctionWithS(const S*) { return 0; }
diff --git a/benchmarks/lit.cfg.py b/benchmarks/lit.cfg.py
new file mode 100644
index 000000000..84857d570
--- /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 000000000..e3ce8b222
--- /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/string.bench.cpp b/benchmarks/string.bench.cpp
index d7f919b14..b8f97e6e2 100644
--- a/benchmarks/string.bench.cpp
+++ b/benchmarks/string.bench.cpp
@@ -195,21 +195,21 @@ 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)>::type Storage[2];
+ std::aligned_storage<sizeof(std::string), alignof(std::string)>::type Storage[2];
using S = std::string;
- S* Data = reinterpret_cast<S*>(Storage);
size_t I = 0;
- new (static_cast<void*>(Data)) std::string(makeString(Length()));
+ 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,
- new (static_cast<void*>(Storage + I)) S(std::move(Data[I ^ 1]));
+ S *tmpS = new (static_cast<void*>(Storage + I)) S(std::move(*newS));
// then destroy the old one.
- Data[I ^ 1].~S();
+ newS->~S();
+ newS = tmpS;
}
- Data[I].~S();
+ newS->~S();
}
static std::string name() { return "BM_StringMove" + Length::name(); }
diff --git a/cmake/Modules/HandleCompilerRT.cmake b/cmake/Modules/HandleCompilerRT.cmake
index 2e0e69e5e..1ce256574 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/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake
index 24fe0c5d5..fb60318a3 100644
--- a/cmake/Modules/HandleLibcxxFlags.cmake
+++ b/cmake/Modules/HandleLibcxxFlags.cmake
@@ -45,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 66cfb7b21..a498c0027 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**:: ``""``
@@ -370,7 +388,9 @@ The following options allow building libc++ for a different ABI version.
.. 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.
+ 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
diff --git a/docs/DesignDocs/AvailabilityMarkup.rst b/docs/DesignDocs/AvailabilityMarkup.rst
index b8b445097..4e6d80b50 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/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 4cf5182a7..20be9f627 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -48,3 +48,15 @@ API Changes
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 43c0684dc..ebbbf628a 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 41f410684..899656cca 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++
diff --git a/fuzzing/fuzzing.cpp b/fuzzing/fuzzing.cpp
index 8888cbeac..ad377bcac 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 0ccf977b6..73f7cfc4d 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -69,7 +69,6 @@ set(files
experimental/chrono
experimental/coroutine
experimental/deque
- experimental/dynarray
experimental/filesystem
experimental/forward_list
experimental/functional
diff --git a/include/__config b/include/__config
index 11ddd59f9..7fefb3b93 100644
--- a/include/__config
+++ b/include/__config
@@ -95,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
@@ -713,7 +715,11 @@ typedef __char32_t char32_t;
#endif
#ifndef _LIBCPP_EXPORTED_FROM_ABI
-# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
+# 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
@@ -971,14 +977,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_LIBRARY_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
+# 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__)
@@ -986,11 +992,6 @@ 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_LIBRARY_ALIGNED_ALLOCATION
-# endif
-# endif
#endif // defined(__APPLE__)
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
@@ -1007,6 +1008,10 @@ template <unsigned> struct __static_assert_check {};
#define _LIBCPP_WCTYPE_IS_MASK
#endif
+#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)
@@ -1143,6 +1148,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__) || \
@@ -1248,8 +1254,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)
@@ -1303,9 +1313,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))) \
@@ -1329,8 +1345,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
@@ -1342,26 +1358,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)
diff --git a/include/__hash_table b/include/__hash_table
index 69ed8dd8b..6f5b18310 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_;
diff --git a/include/__string b/include/__string
index 44c55987f..1ddeec714 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/__tree b/include/__tree
index aa7370bfb..814851085 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;
@@ -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
@@ -1855,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());
}
diff --git a/include/__tuple b/include/__tuple
index 69d6ee961..3b23d78af 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 f119d2520..d102899f2 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -3637,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)
diff --git a/include/any b/include/any
index e2945bdfa..781eee786 100644
--- a/include/any
+++ b/include/any
@@ -94,7 +94,7 @@ namespace std {
#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;
@@ -106,6 +106,7 @@ _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
@@ -577,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>;
@@ -591,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>;
@@ -605,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 8f4e111ac..56f688765 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>>;
@@ -430,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/bitset b/include/bitset
index 6e28596d0..98947e027 100644
--- a/include/bitset
+++ b/include/bitset
@@ -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/chrono b/include/chrono
index 75258abd2..96759f986 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
@@ -92,9 +92,9 @@ public:
// 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;
@@ -134,8 +134,8 @@ public:
// 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
@@ -808,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
@@ -924,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
@@ -1081,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;
@@ -1369,8 +1374,8 @@ public:
// 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
@@ -1581,10 +1586,27 @@ typedef system_clock high_resolution_clock;
#endif
#if _LIBCPP_STD_VER > 17
+// [time.clock.file], type file_clock
+using file_clock = _VSTD_FS::_FilesystemClock;
-struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; };
+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;
@@ -1803,21 +1825,36 @@ private:
unsigned char __wd;
public:
weekday() = default;
- explicit inline constexpr weekday(unsigned __val) noexcept: __wd(static_cast<unsigned char>(__val)) {}
-// inline constexpr weekday(const sys_days& dp) noexcept;
-// explicit constexpr weekday(const local_days& dp) noexcept;
+ 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;
- explicit inline constexpr operator unsigned() const noexcept { return __wd; }
+ 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;
+ 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); }
@@ -2212,6 +2249,7 @@ constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noe
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:
@@ -2223,24 +2261,66 @@ public:
inline constexpr year_month_day(
const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept
: __y{__yval}, __m{__mval}, __d{__dval} {}
-// inline constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;
-// inline constexpr year_month_day(const sys_days& dp) noexcept;
-// inline explicit constexpr year_month_day(const local_days& dp) noexcept;
+ 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::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;
-// inline explicit constexpr operator local_days() const noexcept;
+ 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()}; }
-// TODO: This is not quite correct; requires the calendar bits to do right
-// d_ is in the range [1d, (y_/m_/last).day()],
- inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __d.ok(); }
+ 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(); }
@@ -2338,16 +2418,30 @@ public:
constexpr year_month_day_last& operator+=(const years& __y) noexcept;
constexpr year_month_day_last& operator-=(const years& __y) noexcept;
- constexpr chrono::year year() const noexcept { return __y; }
- constexpr chrono::month month() const noexcept { return __mdl.month(); }
- constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; }
-// constexpr chrono::day day() const noexcept;
-// constexpr operator sys_days() const noexcept;
-// explicit constexpr operator local_days() const noexcept;
- constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); }
+ 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(); }
@@ -2420,6 +2514,15 @@ inline constexpr year_month_day_last& year_month_day_last::operator-=(const mont
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;
@@ -2429,8 +2532,10 @@ public:
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& dp) noexcept;
-// explicit constexpr year_month_weekday(const local_days& dp) noexcept;
+ 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;
@@ -2442,17 +2547,38 @@ public:
inline constexpr unsigned index() const noexcept { return __wdi.index(); }
inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; }
-// constexpr operator sys_days() const noexcept;
-// explicit constexpr operator local_days() const noexcept;
+ 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(); }
@@ -2529,12 +2655,23 @@ public:
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; }
-// constexpr operator sys_days() const noexcept;
-// explicit constexpr operator local_days() const noexcept;
+ 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(); }
@@ -2689,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/deque b/include/deque
index 414c7a859..6f7d04be5 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
*/
@@ -987,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:
@@ -1156,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
{
@@ -2342,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);
@@ -2604,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() +
@@ -2854,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
{
@@ -2927,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 7fd92798b..fdd83d10c 100644
--- a/include/exception
+++ b/include/exception
@@ -164,7 +164,7 @@ public:
};
template<class _Ep>
-exception_ptr
+_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -223,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 1dcdd0f25..d9c953425 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 591cf7160..30c7e4a9d 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/dynarray b/include/experimental/dynarray
deleted file mode 100644
index e2bfa2e43..000000000
--- 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, size_t __count) noexcept {
- _VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), sizeof(value_type) * __count, __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_, __size_);
-}
-
-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/numeric b/include/experimental/numeric
index 14a664011..19c65313f 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 d68cefdf6..6eb4a2618 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 9c2bf2e46..52c12004d 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 f13bff54d..100bdfe72 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 7937357fa..1cf84ee01 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 1f37a6293..6d71bb559 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 339bb252f..af713a063 100644
--- a/include/filesystem
+++ b/include/filesystem
@@ -259,36 +259,6 @@ _LIBCPP_PUSH_MACROS
_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 {
@@ -1181,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 {
@@ -1197,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 f9a71f033..b506acd1f 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
*/
@@ -1744,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 332b4747c..711e484e2 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 61c87b02c..1fb44f271 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>
{
@@ -1468,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>
@@ -1489,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;
@@ -1532,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();
}
@@ -1543,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>
@@ -1559,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);
}
@@ -1568,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
@@ -1579,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;
}
@@ -1592,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) &&
+ alignof(_Fun) <= 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>
@@ -1599,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>,
@@ -1632,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>>
@@ -1643,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>
@@ -1675,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>
@@ -1695,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>
@@ -1828,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;
}
@@ -1848,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;
}
@@ -1867,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
@@ -1929,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>
@@ -1939,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>
@@ -1949,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
@@ -2527,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/iosfwd b/include/iosfwd
index d4384859e..31f1902e5 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 e46881efe..30ee4f4b8 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)
@@ -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)
@@ -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 aed0525db..bda177e11 100644
--- a/include/iterator
+++ b/include/iterator
@@ -438,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:
@@ -479,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 f530507f7..5ea9a9e6f 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 8f0e1db1f..c69e31d93 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
*/
@@ -1170,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
@@ -2450,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 7be358e4d..ac589d360 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)
{
diff --git a/include/map b/include/map
index 472ac314b..616bb46cf 100644
--- a/include/map
+++ b/include/map
@@ -254,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
@@ -465,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
*/
@@ -486,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
{
@@ -900,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");
@@ -1323,33 +1332,33 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
- template <class _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(map<key_type, mapped_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(map<key_type, mapped_type, _C2, allocator_type>&& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multimap<key_type, mapped_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multimap<key_type, mapped_type, _C2, allocator_type>&& __source)
+ void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
@@ -1612,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
@@ -1626,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");
@@ -1942,33 +1960,33 @@ public:
return __tree_.template __node_handle_extract<node_type>(
__it.__i_);
}
- template <class _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multimap<key_type, mapped_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multimap<key_type, mapped_type, _C2, allocator_type>&& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(map<key_type, mapped_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(map<key_type, mapped_type, _C2, allocator_type>&& __source)
+ void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
@@ -2148,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 783d94c72..93f04c6fa 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
@@ -984,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);}
@@ -1460,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 _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 {};
-#else // _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class _Args>
-struct __has_construct
- : false_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
@@ -1510,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
{
@@ -1571,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
@@ -1613,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));
}
@@ -1622,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
@@ -1647,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;
}
}
@@ -1686,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
@@ -1721,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>
diff --git a/include/module.modulemap b/include/module.modulemap
index 681c80bea..6d88f5211 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -524,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/new b/include/new
index 412d51bd0..24ffcad5a 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:
@@ -156,20 +150,6 @@ _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_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
!defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME)
#ifndef _LIBCPP_CXX03_LANG
@@ -350,21 +330,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
_DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
}
-#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
-_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
-#ifndef _LIBCPP_NO_EXCEPTIONS
-_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
-#endif
-void __throw_bad_array_length()
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw bad_array_length();
-#else
- _VSTD::abort();
-#endif
-}
-#endif
-
template <class _Tp>
_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
diff --git a/include/optional b/include/optional
index 9ef0aac39..70422068e 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> &&);
@@ -169,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:
@@ -186,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();
@@ -933,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())
@@ -941,6 +943,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type& value() &
{
if (!this->has_value())
@@ -949,6 +952,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type&& value() &&
{
if (!this->has_value())
@@ -957,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 ef34f71c1..d700a369b 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
@@ -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/regex b/include/regex
index b415903b2..5ac2c1ab4 100644
--- a/include/regex
+++ b/include/regex
@@ -996,6 +996,10 @@ public:
static const char_class_type __regex_word = 0x8000;
#elif 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
diff --git a/include/set b/include/set
index 80cc7b04c..a0155f0b2 100644
--- a/include/set
+++ b/include/set
@@ -216,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
@@ -412,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
*/
@@ -445,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");
@@ -513,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
@@ -569,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
@@ -707,33 +714,33 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
- template <class _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(set<key_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(set<key_type, _C2, allocator_type>&& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multiset<key_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multiset<key_type, _C2, allocator_type>&& __source)
+ void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
@@ -911,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
@@ -925,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");
@@ -984,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
@@ -1048,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
@@ -1185,33 +1200,33 @@ public:
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
- template <class _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multiset<key_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(multiset<key_type, _C2, allocator_type>&& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(set<key_type, _C2, allocator_type>& __source)
+ 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 _C2>
+ template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
- void merge(set<key_type, _C2, allocator_type>&& __source)
+ void merge(set<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
@@ -1390,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 fbde0cf13..3daf74d26 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -144,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_;
@@ -161,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 ea7aecb58..cebe98760 100644
--- a/include/span
+++ b/include/span
@@ -23,20 +23,6 @@ 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 :
@@ -539,36 +525,6 @@ 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
diff --git a/include/streambuf b/include/streambuf
index 1739d58a1..dd293dc63 100644
--- a/include/streambuf
+++ b/include/streambuf
@@ -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 807e14a1d..fb838d1e5 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;
@@ -580,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);
@@ -955,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
@@ -1009,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);
@@ -1671,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()
{
@@ -1681,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
@@ -1711,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)
{
@@ -1722,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)
@@ -1801,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");
@@ -1812,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)
{
@@ -1853,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)
@@ -1871,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)
{
@@ -1916,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);
@@ -1954,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)
@@ -2065,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);
@@ -2076,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)
@@ -2090,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)
{
@@ -2101,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)
@@ -2265,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)
@@ -2277,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
@@ -2293,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))
@@ -2427,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)
{
@@ -2510,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)
{
@@ -2687,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)
{
@@ -2757,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)
{
@@ -2877,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)
{
@@ -2921,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)
{
@@ -2930,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)
{
@@ -2938,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)
{
@@ -2946,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)
{
@@ -2978,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)
{
@@ -2996,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)
{
@@ -3013,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()
{
@@ -3035,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
{
@@ -3053,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)
{
@@ -3082,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
{
@@ -3158,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
{
@@ -3167,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
{
@@ -3194,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()
{
@@ -3203,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
{
@@ -3212,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()
{
@@ -3221,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
{
@@ -3242,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
{
@@ -3250,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
@@ -3298,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
@@ -3323,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
@@ -3356,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
@@ -3381,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
@@ -3414,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
@@ -3439,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
@@ -3450,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
@@ -3472,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
@@ -3497,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
@@ -3508,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
@@ -3530,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
@@ -3555,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
@@ -3566,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
@@ -3589,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
@@ -3614,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
@@ -3625,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
@@ -3660,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
{
@@ -3706,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,
@@ -3764,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
{
@@ -3782,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
{
@@ -4036,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)
{
@@ -4132,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);
@@ -4236,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>
@@ -4293,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 55dce7271..7d783122f 100644
--- a/include/string_view
+++ b/include/string_view
@@ -769,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;
@@ -778,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
@@ -807,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/tuple b/include/tuple
index fb5428ec1..4cc69030b 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
@@ -1078,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 aadb97ba9..ab010716f 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -709,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 {};
diff --git a/include/typeinfo b/include/typeinfo
index 92f1e2255..841153286 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
diff --git a/include/unordered_map b/include/unordered_map
index 6f60749c9..6035b05dc 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -384,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,
@@ -414,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
{
@@ -482,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
{
@@ -845,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;
@@ -1623,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,
@@ -1667,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;
@@ -2239,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 de23ca2a3..b4e61da89 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -339,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,
@@ -384,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;
@@ -933,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,
@@ -976,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;
@@ -1495,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 30e26f163..3fa0bc4c7 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> >;
@@ -409,13 +409,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<
@@ -423,6 +427,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<
@@ -430,6 +436,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<
@@ -437,6 +445,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<
@@ -444,6 +454,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<
@@ -451,6 +463,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<
@@ -458,6 +472,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<
@@ -465,6 +481,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<
@@ -487,6 +505,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()) {}
@@ -616,32 +636,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));
}
@@ -658,7 +683,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>
@@ -989,8 +1014,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;
diff --git a/include/variant b/include/variant
index f9505bf27..a4339de6c 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);
@@ -219,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;
};
@@ -232,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();
@@ -1065,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 (...) {
@@ -1321,6 +1322,7 @@ constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
template <size_t _Ip, class _Vp>
inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
constexpr auto&& __generic_get(_Vp&& __v) {
using __variant_detail::__access::__variant;
if (!__holds_alternative<_Ip>(__v)) {
@@ -1331,6 +1333,7 @@ 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));
@@ -1340,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));
@@ -1349,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));
@@ -1358,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));
@@ -1367,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);
@@ -1374,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>(
@@ -1382,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);
@@ -1389,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>(
@@ -1521,6 +1531,7 @@ constexpr bool operator>=(const variant<_Types...>& __lhs,
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 196ea70ea..edb6d3e09 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
*/
@@ -3408,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 aca84f8ed..d6ccb138f 100644
--- a/include/version
+++ b/include/version
@@ -30,6 +30,8 @@ __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>
@@ -37,6 +39,9 @@ __cpp_lib_complex_udls 201309L <complex>
__cpp_lib_concepts 201806L <concepts>
__cpp_lib_constexpr_swap_algorithms 201806L <algorithm>
__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>
@@ -114,6 +119,10 @@ __cpp_lib_void_t 201411L <type_traits>
#endif
#if _LIBCPP_STD_VER > 17
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+# define __cpp_lib_char8_t 201811L
+#endif
+#define __cpp_lib_erase_if 201811L
#endif
#endif // _LIBCPP_VERSIONH
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1fa315b06..24489e8fb 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(
@@ -153,71 +153,91 @@ if (LIBCXX_OSX_REEXPORT_SYSTEM_ABI_LIBRARY)
"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})
+
+ # 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(cxx_objects
- PROPERTIES
- COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
-)
+ 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()
@@ -244,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 eb6369368..38dffd290 100644
--- a/lib/abi/CHANGELOG.TXT
+++ b/lib/abi/CHANGELOG.TXT
@@ -16,7 +16,73 @@ New entries should be added directly below the "Version" header.
Version 8.0
-----------
-* r345260 - Making libc++ build under -fvisibility=hidden
+* 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,
diff --git a/lib/abi/x86_64-apple-darwin.v1.abilist b/lib/abi/x86_64-apple-darwin.v1.abilist
index 88cfa90f1..65a034961 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'}
@@ -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 3896b38d9..5880a3bfd 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'}
@@ -530,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'}
@@ -1721,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}
@@ -2013,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}
@@ -2206,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 f8af75793..0be9eb2fc 100644
--- a/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
+++ b/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
@@ -1123,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'}
@@ -1142,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}
@@ -1262,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'}
@@ -1447,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'}
@@ -1458,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 0059eb49e..40c055dae 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/filesystem/filesystem_common.h b/src/filesystem/filesystem_common.h
index ed92877c4..40419ee35 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 c9396b59c..e3bbc7b64 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:
@@ -1294,7 +1306,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;
@@ -1454,7 +1478,7 @@ static int DetermineLexicalElementCount(PathParser PP) {
auto Elem = *PP;
if (Elem == "..")
--Count;
- else if (Elem != ".")
+ else if (Elem != "." && Elem != "")
++Count;
}
return Count;
@@ -1468,8 +1492,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())
@@ -1501,6 +1524,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;
@@ -1514,21 +1541,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/support/runtime/exception_fallback.ipp b/src/support/runtime/exception_fallback.ipp
index 664e7f48c..16d387b99 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 0f78932f6..dda4432b5 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 6d9e0cff5..52fe8635d 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 87d5a66fc..042d3add6 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 550da8ea7..241cfee23 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 f8442460a..9435744d3 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/half_positive.pass.cpp b/test/libcxx/algorithms/half_positive.pass.cpp
index 178055cbb..7dcfc2c92 100644
--- a/test/libcxx/algorithms/half_positive.pass.cpp
+++ b/test/libcxx/algorithms/half_positive.pass.cpp
@@ -9,11 +9,8 @@
// <algorithm>
-// template <typename _Tp> _Tp __half_positive(const _Tp&);
-
-// __half_positive divide integer number by 2 as unsigned number
-// if it's safe to do so. It can be an important optimization for lower bound,
-// for example.
+// __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>
diff --git a/test/libcxx/containers/associative/non_const_comparator.fail.cpp b/test/libcxx/containers/associative/non_const_comparator.fail.cpp
index ea0d9ac09..ddd796089 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/containers/sequences/deque/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/deque/pop_back_empty.pass.cpp
new file mode 100644
index 000000000..e4f5d0b01
--- /dev/null
+++ b/test/libcxx/containers/sequences/deque/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.
+//
+//===----------------------------------------------------------------------===//
+
+// <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() {
+ 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/pop_back_empty.pass.cpp b/test/libcxx/containers/sequences/vector/pop_back_empty.pass.cpp
new file mode 100644
index 000000000..388dfa4e1
--- /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 000000000..998d0b74e
--- /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 000000000..c4950fbe6
--- /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 8adc67589..f428ab9ac 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/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp b/test/libcxx/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
index 1847dac2e..beb560800 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/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index 9ad8df4dd..5a0f2ba72 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -145,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 c6a83cc61..000000000
--- 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 db7484d46..000000000
--- 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 400984135..000000000
--- 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 5c745e0d1..000000000
--- 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 1ed51538f..000000000
--- 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 473313f39..000000000
--- 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 f0aa1e3ff..000000000
--- 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 a5484296f..000000000
--- 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 0ba27cf92..000000000
--- 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 4306d1e9c..000000000
--- 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 ab4960035..000000000
--- 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 93553b513..000000000
--- 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 000000000..074a9c58c
--- /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 000000000..c4fb9593a
--- /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 40bacbcba..b2150fcd2 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 ccb9b710e..ffcedf0bf 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 000000000..32fd0527d
--- /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 000000000..37ac584a7
--- /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 000000000..64f737420
--- /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 000000000..417982e36
--- /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/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp
index b58f5c55b..0bcda7056 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/utilities/any/use_header_warning.fail.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
-}
+// 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 000000000..bc37d8b4d
--- /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 000000000..1711d2f03
--- /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 000000000..ef011bbe4
--- /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 000000000..d9a01337a
--- /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 000000000..8ebb347a4
--- /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 000000000..9f3d679fc
--- /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 000000000..5544a3f0e
--- /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 000000000..520e9fbb4
--- /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 000000000..c7c9e5728
--- /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 000000000..0f8defcbd
--- /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 ddef5d00e..7e3130cf9 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/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp b/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp
deleted file mode 100644
index c37d23433..000000000
--- a/test/libcxx/language.support/support.dynamic/alloc.errors/new.badlength/bad_array_length.pass.cpp
+++ /dev/null
@@ -1,37 +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
-
-// 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
-
-#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);
-}
diff --git a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
index 0f6b243e5..f62e82d8e 100644
--- a/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -7,19 +7,30 @@
//
//===----------------------------------------------------------------------===//
-// 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
// definitions, which does not yet provide aligned allocation
// XFAIL: LIBCXX-WINDOWS-FIXME
-// XFAIL: with_system_cxx_lib=macosx10.12 || availability=macosx10.12
-// XFAIL: with_system_cxx_lib=macosx10.11 || availability=macosx10.11
-// XFAIL: with_system_cxx_lib=macosx10.10 || availability=macosx10.10
-// XFAIL: with_system_cxx_lib=macosx10.9 || availability=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.8 || availability=macosx10.8
-// XFAIL: with_system_cxx_lib=macosx10.7 || availability=macosx10.7
+// 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
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 388fbebbd..d7b4cca63 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/memory/aligned_allocation_macro.pass.cpp b/test/libcxx/memory/aligned_allocation_macro.pass.cpp
index 0e13b15f2..368076dee 100644
--- a/test/libcxx/memory/aligned_allocation_macro.pass.cpp
+++ b/test/libcxx/memory/aligned_allocation_macro.pass.cpp
@@ -9,13 +9,17 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// aligned allocation functions are not provided prior to macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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.8
+// XFAIL: availability=macosx10.7
#include <new>
diff --git a/test/libcxx/min_max_macros.sh.cpp b/test/libcxx/min_max_macros.sh.cpp
index 45b7bb1f6..7b9202d95 100644
--- a/test/libcxx/min_max_macros.sh.cpp
+++ b/test/libcxx/min_max_macros.sh.cpp
@@ -241,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/resize_default_initialized.pass.cpp b/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp
new file mode 100644
index 000000000..a3fa585e4
--- /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.threads/thread.thread.this/sleep_for.pass.cpp b/test/libcxx/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
index b46c2cdec..3c0571bf9 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 0b9b6e717..cdfb02736 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 000000000..6a3e613e9
--- /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 000000000..6a2401223
--- /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 000000000..edb3bbf64
--- /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 000000000..2dbf5511d
--- /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/pair.tuple_element.fail.cpp b/test/libcxx/utilities/utility/pairs/pairs.pair/pair.tuple_element.fail.cpp
index 2a92240a6..8bfeeea5d 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 000000000..81dad3bc2
--- /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 000000000..5d8d36262
--- /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/variant/variant.variant/variant.helper/variant_alternative.fail.cpp b/test/libcxx/utilities/variant/variant.variant/variant.helper/variant_alternative.fail.cpp
index f39a445b9..c4522682c 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 a836ef516..c309aaaae 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 d769ad850..3d37d052c 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 76ac99165..ac3b95fbe 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/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
index 7a8d4c1f4..43436e65a 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 331a81ff3..04b1f8543 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/index_key.pass.cpp b/test/std/containers/associative/map/map.access/index_key.pass.cpp
index 3b1c21fd5..5f3d109d1 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 e5580bca3..bc91475c2 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.erasure/erase_if.pass.cpp b/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
new file mode 100644
index 000000000..f8cbc15d1
--- /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/merge.pass.cpp b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
index 4fef2425a..bb75e1d60 100644
--- a/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
+++ b/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
#include <map>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
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 000000000..8e786fdc9
--- /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/merge.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
index 71f3c0b39..f0e38c255 100644
--- a/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
#include <map>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
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 a280d10d5..4bd2c88f8 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/merge.pass.cpp b/test/std/containers/associative/multiset/merge.pass.cpp
index 516e27de3..8ab992889 100644
--- a/test/std/containers/associative/multiset/merge.pass.cpp
+++ b/test/std/containers/associative/multiset/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(multiset<Key, C2, Allocator>&& source);
#include <set>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
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 000000000..3c619bb68
--- /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/merge.pass.cpp b/test/std/containers/associative/set/merge.pass.cpp
index 0896596d9..bbae22c77 100644
--- a/test/std/containers/associative/set/merge.pass.cpp
+++ b/test/std/containers/associative/set/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(multiset<key_type, C2, allocator_type>&& source);
#include <set>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
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 000000000..a55a38c2d
--- /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 ead9ad0bc..25f6bc76e 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 bb6ff8f91..6830cb716 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/map_allocator_requirement_test_templates.h b/test/std/containers/map_allocator_requirement_test_templates.h
index 2ae3a2e3c..374970d48 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 593df3ca2..ba2c571eb 100644
--- a/test/std/containers/sequences/array/array.data/data.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data.pass.cpp
@@ -13,6 +13,8 @@
#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 };.
@@ -40,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;
@@ -48,14 +50,14 @@ 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);
}
@@ -64,6 +66,6 @@ int main()
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 e3d9a6907..f46352564 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"
@@ -47,14 +48,14 @@ int main()
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 45e1d2b46..a7e56fcce 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 c9fe695f9..2139fc1ad 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 1c7647221..37c6b5eec 100644
--- a/test/std/containers/sequences/array/begin.pass.cpp
+++ b/test/std/containers/sequences/array/begin.pass.cpp
@@ -14,6 +14,8 @@
#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"
@@ -40,6 +42,11 @@ int main()
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/deque/deque.erasure/erase.pass.cpp b/test/std/containers/sequences/deque/deque.erasure/erase.pass.cpp
new file mode 100644
index 000000000..9a8c698a5
--- /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 000000000..a090eb694
--- /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/erase_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
index f323ca432..3ed17ab3f 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
@@ -32,7 +32,7 @@ struct Throws {
static bool sThrows;
};
-
+
bool Throws::sThrows = false;
#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 391a0f79d..6556ced1a 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
@@ -34,7 +34,7 @@ struct Throws {
static bool sThrows;
};
-
+
bool Throws::sThrows = false;
#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 000000000..0163b8607
--- /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 000000000..69685d2d3
--- /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/resize_size_value.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
index 356e0d657..297e2725a 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/list/list.cons/input_iterator.pass.cpp b/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp
index 3cdcc7362..d2c7fa023 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 000000000..a9f65c053
--- /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 000000000..99b1c6530
--- /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/vector.bool/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
index 0f51c219e..80bfce1ad 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 4e71df374..e2d94e225 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 ab2b7ce6d..b3663c759 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.cons/construct_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
index 88613efe7..60fe2899a 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 71743b31d..15498ba41 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 b244f75f2..f8c932a02 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.erasure/erase.pass.cpp b/test/std/containers/sequences/vector/vector.erasure/erase.pass.cpp
new file mode 100644
index 000000000..e88252f1d
--- /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 000000000..8025a3407
--- /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/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
index 258b9d9f7..b54a96d0b 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 2e3346f47..517c36d8e 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 cffc1dbd4..2761bf177 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 000000000..f6a580c21
--- /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/unord.map.cnstr/assign_copy.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
index b793f0934..c6b92744e 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 9fca1f105..6bfb7bc18 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 0d08fae0c..af98b923d 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 b06e4db13..1979dd326 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 3dbcf4d15..94c4bca9b 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/index.pass.cpp b/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp
index 7bc59447a..f7f3a22d5 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/merge.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp
index d525b1add..2d5e1843f 100644
--- 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
@@ -23,6 +23,7 @@
// 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"
@@ -40,9 +41,6 @@ struct throw_hasher
throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
- typedef size_t result_type;
- typedef T argument_type;
-
size_t operator()(const T& p) const
{
if (should_throw_)
@@ -98,8 +96,6 @@ int main()
struct hasher
{
hasher() = default;
- typedef Counter<int> argument_type;
- typedef size_t result_type;
size_t operator()(const Counter<int>& p) const
{
return std::hash<Counter<int>>()(p);
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 382ed7c98..65c9f8c12 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 17eb14e44..10fafee80 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 000000000..dc613269a
--- /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 504fe54de..2976d2c3c 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/rehash.pass.cpp b/test/std/containers/unord/unord.multimap/rehash.pass.cpp
index 22202ccb6..e8394d7f7 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 d86c69c88..003337774 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 8c5ddab05..3f0259794 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 62e756cda..d5729e350 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 cefbf4596..f06ed700f 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 9bd55ac92..11a1759bb 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 1a222cef1..b3519fd50 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 11465edae..7baf11f52 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/merge.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp
index d01862094..b7f61ca5a 100644
--- 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
@@ -23,6 +23,7 @@
// 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"
@@ -40,9 +41,6 @@ struct throw_hasher
throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
- typedef size_t result_type;
- typedef T argument_type;
-
size_t operator()(const T& p) const
{
if (should_throw_)
@@ -98,8 +96,6 @@ int main()
struct hasher
{
hasher() = default;
- typedef Counter<int> argument_type;
- typedef size_t result_type;
size_t operator()(const Counter<int>& p) const
{
return std::hash<Counter<int>>()(p);
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 000000000..7a9d93d43
--- /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 a4f703df8..14eb7c477 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 ad7bc043a..4b6e2f769 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/merge.pass.cpp b/test/std/containers/unord/unord.multiset/merge.pass.cpp
index 0bf8d358f..7913f9564 100644
--- a/test/std/containers/unord/unord.multiset/merge.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source);
#include <unordered_set>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
@@ -40,9 +41,6 @@ struct throw_hasher
throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
- typedef size_t result_type;
- typedef T argument_type;
-
size_t operator()(const T& p) const
{
if (should_throw_)
@@ -98,8 +96,6 @@ int main()
struct hasher
{
hasher() = default;
- typedef Counter<int> argument_type;
- typedef size_t result_type;
size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); }
};
{
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 b7557c437..e1794c0d8 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 ce664034d..5ab0209ce 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 dfcb63e6e..17ac618fa 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 df49abe07..d98b9a7d0 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 a2ee74679..fd3b76316 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/erase_if.pass.cpp b/test/std/containers/unord/unord.set/erase_if.pass.cpp
new file mode 100644
index 000000000..e060fda1f
--- /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 4e49a86ef..ca8250c1e 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/merge.pass.cpp b/test/std/containers/unord/unord.set/merge.pass.cpp
index ebf03cd56..519d7f138 100644
--- a/test/std/containers/unord/unord.set/merge.pass.cpp
+++ b/test/std/containers/unord/unord.set/merge.pass.cpp
@@ -23,6 +23,7 @@
// void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source);
#include <unordered_set>
+#include <cassert>
#include "test_macros.h"
#include "Counter.h"
@@ -40,9 +41,6 @@ struct throw_hasher
throw_hasher(bool& should_throw) : should_throw_(should_throw) {}
- typedef size_t result_type;
- typedef T argument_type;
-
size_t operator()(const T& p) const
{
if (should_throw_)
@@ -98,8 +96,6 @@ int main()
struct hasher
{
hasher() = default;
- typedef Counter<int> argument_type;
- typedef size_t result_type;
size_t operator()(const Counter<int>& p) const { return std::hash<Counter<int>>()(p); }
};
{
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 0859d8edc..cf473a930 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 4f7ccfec6..4e0f68c71 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 bc3658243..f89c45caf 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 7ba340bf9..ff46e08f4 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 5bcc288aa..b6ad0e2a1 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 963054580..000000000
--- 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 8ec1b9a59..000000000
--- 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 345a291a6..000000000
--- 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 f2fbc8609..000000000
--- 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 1a7de292e..000000000
--- 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 ecf05b317..000000000
--- 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 7ef49fc47..e1e5deea5 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 80a0f07f6..72a86654e 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 b5bd7ae00..cb2100461 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 ecd7fcb91..c8f6830fb 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 478a3dac5..401f41e07 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 2cfffbbd4..c123acb6a 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 e72c09149..098215c83 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 d1fefe5b3..813939f39 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 f7e496696..b7d01c9e2 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 db24e3d26..9ab87f541 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 7302759bc..c4e9545e9 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 a55f0592a..bd4dbab8f 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 afb525e73..c2bceec48 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 1fa71551b..69e879e2e 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 b2024ce12..5fdbab227 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 1832ac2ba..27623a4c9 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 3bc6fbbe5..ceb2eca17 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 a88f44104..801eca428 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 c8b9900bc..cd8d70958 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 7b5455507..54ff8ebf7 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>
diff --git a/test/std/containers/views/span.iterators/rbegin.pass.cpp b/test/std/containers/views/span.iterators/rbegin.pass.cpp
index c0776c00a..258908d6c 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 abcead445..367ea8866 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 b081b95c3..e4a240f8d 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 28a4c45d2..63d79c923 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 24e3fb273..54216c297 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 a48c0d024..23e55bb76 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 c33fd3f6c..16f1b6a7e 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 1ee75d9fc..3b6c5b0e2 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 3bfdab9f8..e745fd77d 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 4e378fe54..94d41430b 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 79cdc7bca..012fc2b5f 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 082abeb77..c519fbf76 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/math_h.pass.cpp b/test/std/depr/depr.c.headers/math_h.pass.cpp
index 7e1b2d110..e8341a07f 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/uchar_h.pass.cpp b/test/std/depr/depr.c.headers/uchar_h.pass.cpp
index f12169845..be4ea0dae 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.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 c829a97b4..652100c97 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/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 7ec814b21..a641e9237 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 71e8e55ae..1aa177505 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 7791097dc..2be6122a0 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 52c577bc8..f4e1d2f74 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 000000000..e0b3a959c
--- /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 09498bf21..2a291d61d 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 000000000..00eafe532
--- /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 bfc818924..2d30cc3b8 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 04bc2dd1d..9807309f4 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 bc77f3f63..bf0096acf 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 cbe2b2d09..b5fb838dd 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 5f7b30dd6..ec4fc6d91 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 e240c6496..940f886f9 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 1ea1d780c..34b65f52d 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 553c2b2eb..7c653f348 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 342e33724..92b6c726e 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 dae74f040..915efd081 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 25687db16..8d1261137 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 62e44f542..22a760da6 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 70f1c2010..b815246d6 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 07fa5a79e..1e98b7dfd 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 a00c7a1dd..82e460db9 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.unformatted/get.pass.cpp b/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
index c7f16ca7e..0f356e26d 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 b3d3c69b4..cf06e343b 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 a45802c57..83fd40bef 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 437af84f9..8b42bae55 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 7ee2c2956..f17aa1623 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 1bce3fa5d..5c6a3c59f 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 3a37cffce..3095712b9 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 ceef0d28f..20e70cfbd 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 a0a8e2f1b..01eecb5d8 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 e370b4bfb..dc4e0ba0d 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 cac1e3955..3b7417ab2 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 956cd171a..c23b3028c 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 6c01fc057..b0b3c31f7 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 e2776a5d1..0a2fb36ec 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 a4d923d70..e8600972d 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 5aaf38444..11532711a 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 0bea4b986..e04677fa3 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 9bd96984e..3242bcc94 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/iterators/iterator.primitives/iterator.traits/empty.fail.cpp b/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp
new file mode 100644
index 000000000..021523481
--- /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::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoDifference> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoValue> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoPointer> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoReference> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}}
+ }
+
+ {
+ typedef std::iterator_traits<NotAnIteratorNoCategory> T;
+ typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}}
+ typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::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 38f7c0b6b..34f430ff3 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/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 52aeea314..4dd9390c4 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
@@ -17,22 +17,25 @@
// None of the current GCC compilers support this.
// UNSUPPORTED: gcc-5, gcc-6
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 1d20b33a0..d6194b00a 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,22 +15,25 @@
// FIXME change this to XFAIL.
// UNSUPPORTED: no-aligned-allocation && !gcc
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 60ebdd8e9..59878aefd 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,22 +15,25 @@
// FIXME turn this into an XFAIL
// UNSUPPORTED: no-aligned-allocation && !gcc
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 b09316487..fc713dbf8 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,24 +10,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: sanitizer-new-delete
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so our
-// custom aligned allocation functions are not called and the test fails
-// 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
-
-// Our custom aligned allocation functions are not called when deploying to
-// platforms older than macosx10.13, since those platforms don't support
-// aligned allocation.
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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/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 f71cf19cc..ab25a9be0 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 5885218c4..19cabcce1 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
@@ -16,22 +16,25 @@
// None of the current GCC compilers support this.
// UNSUPPORTED: gcc-5, gcc-6
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 52db4c56c..7cf1aca3b 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,22 +9,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 a5e40a0d2..dd2666e00 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,22 +9,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so that's a link error
-// 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
-
-// Using aligned allocation functions is a compiler error when deploying to
-// platforms older than macosx10.13
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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 de1bd8d82..514a2b8af 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,24 +10,25 @@
// UNSUPPORTED: c++98, c++03, c++11, c++14
// UNSUPPORTED: sanitizer-new-delete
-// dylibs shipped before macosx10.13 do not provide aligned allocation, so our
-// custom aligned allocation functions are not called and the test fails
-// 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
-
-// Our custom aligned allocation functions are not called when deploying to
-// platforms older than macosx10.13, since those platforms don't support
-// aligned allocation.
-// UNSUPPORTED: macosx10.12
-// UNSUPPORTED: macosx10.11
-// UNSUPPORTED: macosx10.10
-// UNSUPPORTED: macosx10.9
-// UNSUPPORTED: macosx10.8
-// UNSUPPORTED: macosx10.7
+// 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.single/sized_delete_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
index d5b610f71..7d6f34845 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 71f5e4588..034c578bb 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.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 6a46c370e..11772f67d 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 8deb28d3f..8a3ca008d 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 2dfea084b..7dec03d08 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 2c5302cd6..017f8630a 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 0cce48481..b27f5c583 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 e61802054..5096ad211 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 660ecf503..1b087f0cd 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 f8ca2059d..1391f2096 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 759217169..cb5736f5c 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 d68cd5d78..4f43a6532 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 033ecdc31..241f9cc27 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 fa714d5d1..e00afa900 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 b96a0e7fc..8431b733f 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 4408714c1..2e9ac223a 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 79bc5867e..6e321d1ef 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 6a609963d..f6412a97d 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 28570fd22..b7a892605 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 21090aa9c..f505f4142 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 7517aaa19..65d5150a7 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 de771ebe3..158e2791f 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 6b61f7ba4..649310938 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 927585e94..c4c7a30a7 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 e72fbba10..a1e61fcdc 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 245e84414..930d01102 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 b54d46fd5..05891b1f6 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 97166f0c3..5d5597c47 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 98a2a53d1..1514ae841 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 5da5c9513..3c2dc5493 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 645f6f7df..f1fd20035 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 d9df999dd..a0a6d7f84 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 9e2a8431a..901eea4d0 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 23811fada..8e407c225 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
index 37a636f32..24d2f8002 100644
--- 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
@@ -20,6 +20,7 @@
*/
#include <algorithm>
+#include <cassert>
#include "test_macros.h"
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
index 951afbc08..933730442 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <any>
+#include <cassert>
#include "test_macros.h"
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
index 548abe648..5d25c628b 100644
--- 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
@@ -17,6 +17,7 @@
*/
#include <array>
+#include <cassert>
#include "test_macros.h"
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
index 0c15dc539..78ee09d2f 100644
--- 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
@@ -11,6 +11,7 @@
// <atomic> feature macros
/* Constant Value
+ __cpp_lib_char8_t 201811L
__cpp_lib_atomic_is_always_lock_free 201603L
__cpp_lib_atomic_ref 201806L
@@ -19,13 +20,24 @@
// UNSUPPORTED: libcpp-has-no-threads
#include <atomic>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <atomic> are defined.
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_atomic_is_always_lock_free)
# error "__cpp_lib_atomic_is_always_lock_free is not defined"
# elif __cpp_lib_atomic_is_always_lock_free < 201603L
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
index 2dfe4a8b1..5dd7d049a 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <bit>
+#include <cassert>
#include "test_macros.h"
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
index 26147fc54..f1e252f8e 100644
--- 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
@@ -15,6 +15,7 @@
*/
#include <charconv>
+#include <cassert>
#include "test_macros.h"
int main()
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
index 9ec93f39c..1d0a79ec1 100644
--- 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
@@ -17,6 +17,7 @@
*/
#include <chrono>
+#include <cassert>
#include "test_macros.h"
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
index e8479d1c8..b5b0309f8 100644
--- 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
@@ -17,6 +17,7 @@
*/
#include <cmath>
+#include <cassert>
#include "test_macros.h"
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 000000000..eff2cb293
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/compare.version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// <new> feature macros
+
+/* Constant Value
+ __cpp_lib_three_way_comparison 201711L
+
+*/
+
+#include <compare>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <compare> 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/complex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp
index dd64efb11..be25d793d 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <complex>
+#include <cassert>
#include "test_macros.h"
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
index 06f244834..b21239122 100644
--- 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
@@ -17,6 +17,7 @@
// XFAIL
// #include <concepts>
+#include <cassert>
#include "test_macros.h"
int main()
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
index ac8dfbb04..ad743b51e 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <cstddef>
+#include <cassert>
#include "test_macros.h"
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
index faa9063f4..188d2f3c0 100644
--- 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
@@ -12,17 +12,29 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_nonmember_container_access 201411L
*/
#include <deque>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <deque> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index a77ce5f1c..3ea235bdb 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <exception>
+#include <cassert>
#include "test_macros.h"
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
index 4cc630733..2fcd44cd0 100644
--- 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
@@ -7,7 +7,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
+//
// <execution> feature macros
/* Constant Value
@@ -17,6 +17,7 @@
// XFAIL
// #include <execution>
+#include <cassert>
#include "test_macros.h"
int main()
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
index 46ad17d75..4d03634c2 100644
--- 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
@@ -11,18 +11,30 @@
// <filesystem> feature macros
/* Constant Value
+ __cpp_lib_char8_t 201811L
__cpp_lib_filesystem 201703L
*/
#include <filesystem>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <filesystem> are defined.
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_filesystem)
# error "__cpp_lib_filesystem is not defined"
# elif __cpp_lib_filesystem < 201703L
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
index b262d70dd..9b44f6e2c 100644
--- 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
@@ -12,6 +12,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_incomplete_container_elements 201505L
__cpp_lib_list_remove_return_type 201806L
__cpp_lib_nonmember_container_access 201411L
@@ -19,12 +20,23 @@
*/
#include <forward_list>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <forward_list> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index a24de49f3..57978cbb3 100644
--- 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
@@ -20,13 +20,14 @@
*/
#include <functional>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <functional> are defined.
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_invoke)
# error "__cpp_lib_invoke is not defined"
# elif __cpp_lib_invoke < 201411L
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
index 35ed34b50..74ab48e3c 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <iomanip>
+#include <cassert>
#include "test_macros.h"
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 000000000..7ede323ca
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/istream.version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// <istream> feature macros
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L
+
+*/
+
+#include <istream>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <istream> are defined.
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+/*
+#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/iterator.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
index 02e028649..50c582fd8 100644
--- 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
@@ -19,6 +19,7 @@
*/
#include <iterator>
+#include <cassert>
#include "test_macros.h"
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 000000000..7f1869237
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/limits.version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// <limits> feature macros
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L
+
+*/
+
+#include <limits>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <limits> are defined.
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+/*
+#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/list.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/list.version.pass.cpp
index ad666d152..e6e65655b 100644
--- 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
@@ -12,6 +12,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_incomplete_container_elements 201505L
__cpp_lib_list_remove_return_type 201806L
__cpp_lib_nonmember_container_access 201411L
@@ -19,12 +20,23 @@
*/
#include <list>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <list> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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 000000000..602273329
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/locale.version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// <locale> feature macros
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L
+
+*/
+
+#include <locale>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <locale> are defined.
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+/*
+#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/map.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/map.version.pass.cpp
index 933449ce5..e7dbf7d20 100644
--- 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
@@ -12,6 +12,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_generic_associative_lookup 201304L
__cpp_lib_map_try_emplace 201411L
__cpp_lib_node_extract 201606L
@@ -20,12 +21,23 @@
*/
#include <map>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <map> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index 5dbd6ab5f..4ffb7bd80 100644
--- 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
@@ -23,6 +23,7 @@
*/
#include <memory>
+#include <cassert>
#include "test_macros.h"
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
index 30c27233b..857ece267 100644
--- 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
@@ -17,6 +17,7 @@
// XFAIL
// #include <memory_resource>
+#include <cassert>
#include "test_macros.h"
int main()
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
index 1909b31a1..72209d9f4 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <mutex>
+#include <cassert>
#include "test_macros.h"
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
index 6daca346f..6bcd242d1 100644
--- 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
@@ -1,4 +1,3 @@
-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -11,12 +10,14 @@
// <new> feature macros
/* Constant Value
+ __cpp_lib_destroying_delete 201806L
__cpp_lib_hardware_interference_size 201703L
__cpp_lib_launder 201606L
*/
#include <new>
+#include <cassert>
#include "test_macros.h"
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
index fbe100ba8..61547621e 100644
--- 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
@@ -17,6 +17,7 @@
*/
#include <numeric>
+#include <cassert>
#include "test_macros.h"
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
index b78eda604..b9795181a 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <optional>
+#include <cassert>
#include "test_macros.h"
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 000000000..668b39e32
--- /dev/null
+++ b/test/std/language.support/support.limits/support.limits.general/ostream.version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// <ostream> feature macros
+
+/* Constant Value
+ __cpp_lib_char8_t 201811L
+
+*/
+
+#include <ostream>
+#include <cassert>
+#include "test_macros.h"
+
+int main()
+{
+// ensure that the macros that are supposed to be defined in <ostream> are defined.
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
+/*
+#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/regex.version.pass.cpp b/test/std/language.support/support.limits/support.limits.general/regex.version.pass.cpp
index 91222ce64..fdc499328 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <regex>
+#include <cassert>
#include "test_macros.h"
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
index c43069186..84b2dbdb2 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <scoped_allocator>
+#include <cassert>
#include "test_macros.h"
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
index dc414f0fd..716eae6d9 100644
--- 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
@@ -12,6 +12,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_generic_associative_lookup 201304L
__cpp_lib_node_extract 201606L
__cpp_lib_nonmember_container_access 201411L
@@ -19,12 +20,23 @@
*/
#include <set>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <set> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index d432e8beb..33387e890 100644
--- 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
@@ -19,6 +19,7 @@
// UNSUPPORTED: libcpp-has-no-threads
#include <shared_mutex>
+#include <cassert>
#include "test_macros.h"
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
index 2b755b691..87e8c8f96 100644
--- 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
@@ -12,6 +12,8 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
+ __cpp_lib_char8_t 201811L
__cpp_lib_nonmember_container_access 201411L
__cpp_lib_string_udls 201304L
__cpp_lib_string_view 201606L
@@ -19,12 +21,33 @@
*/
#include <string>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <string> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index 53e76821b..bbdeb0b5a 100644
--- 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
@@ -11,17 +11,29 @@
// <string_view> feature macros
/* Constant Value
+ __cpp_lib_char8_t 201811L
__cpp_lib_string_view 201606L
*/
#include <string_view>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <string_view> are defined.
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index 921b8ae93..ddff29d78 100644
--- 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
@@ -19,6 +19,7 @@
*/
#include <tuple>
+#include <cassert>
#include "test_macros.h"
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
index 9f7ecedb5..e53da7ef7 100644
--- 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
@@ -28,13 +28,14 @@
*/
#include <type_traits>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <type_traits> are defined.
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_void_t)
# error "__cpp_lib_void_t is not defined"
# elif __cpp_lib_void_t < 201411L
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
index cf01b4afc..d23a91a30 100644
--- 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
@@ -12,6 +12,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_node_extract 201606L
__cpp_lib_nonmember_container_access 201411L
__cpp_lib_unordered_map_try_emplace 201411L
@@ -19,12 +20,24 @@
*/
#include <unordered_map>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <unordered_map> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index b8e70636c..c4dbed14b 100644
--- 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
@@ -12,18 +12,30 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_node_extract 201606L
__cpp_lib_nonmember_container_access 201411L
*/
#include <unordered_set>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <unordered_set> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index 8f0322d86..dff687f4b 100644
--- 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
@@ -19,6 +19,7 @@
*/
#include <utility>
+#include <cassert>
#include "test_macros.h"
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
index 75f228ba9..5532e0446 100644
--- 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
@@ -16,6 +16,7 @@
*/
#include <variant>
+#include <cassert>
#include "test_macros.h"
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
index f033d4476..e7cb1942c 100644
--- 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
@@ -12,18 +12,30 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L
+ __cpp_lib_erase_if 201811L
__cpp_lib_incomplete_container_elements 201505L
__cpp_lib_nonmember_container_access 201411L
*/
#include <vector>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <vector> are defined.
+#if TEST_STD_VER > 17
+# if !defined(__cpp_lib_erase_if)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_erase_if is not defined");
+# else
+# if __cpp_lib_erase_if < 201811L
+# error "__cpp_lib_erase_if has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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
index e52c188bf..29fe4b298 100644
--- 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
@@ -29,6 +29,7 @@
__cpp_lib_complex_udls 201309L
__cpp_lib_concepts 201806L
__cpp_lib_constexpr_swap_algorithms 201806L
+ __cpp_lib_destroying_delete 201806L
__cpp_lib_enable_shared_from_this 201603L
__cpp_lib_exchange_function 201304L
__cpp_lib_execution 201603L
@@ -75,6 +76,7 @@
__cpp_lib_string_udls 201304L
__cpp_lib_string_view 201606L
__cpp_lib_to_chars 201611L
+ __cpp_lib_three_way_comparison 201711L
__cpp_lib_transformation_trait_aliases 201304L
__cpp_lib_transparent_operators 201510L
__cpp_lib_tuple_element_t 201402L
@@ -88,13 +90,14 @@
*/
#include <version>
+#include <cassert>
#include "test_macros.h"
int main()
{
// ensure that the macros that are supposed to be defined in <version> are defined.
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_atomic_is_always_lock_free)
# error "__cpp_lib_atomic_is_always_lock_free is not defined"
# elif __cpp_lib_atomic_is_always_lock_free < 201603L
@@ -102,7 +105,7 @@ int main()
# endif
#endif
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_filesystem)
# error "__cpp_lib_filesystem is not defined"
# elif __cpp_lib_filesystem < 201703L
@@ -110,7 +113,7 @@ int main()
# endif
#endif
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_invoke)
# error "__cpp_lib_invoke is not defined"
# elif __cpp_lib_invoke < 201411L
@@ -118,7 +121,7 @@ int main()
# endif
#endif
-#if _TEST_STD_VER > 14
+#if TEST_STD_VER > 14
# if !defined(__cpp_lib_void_t)
# error "__cpp_lib_void_t is not defined"
# elif __cpp_lib_void_t < 201411L
@@ -126,6 +129,16 @@ int main()
# endif
#endif
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+# if !defined(__cpp_lib_char8_t)
+ LIBCPP_STATIC_ASSERT(false, "__cpp_lib_char8_t is not defined");
+# else
+# if __cpp_lib_char8_t < 201811L
+# error "__cpp_lib_char8_t has an invalid value"
+# endif
+# endif
+#endif
+
/*
#if !defined(__cpp_lib_fooby)
# error "__cpp_lib_fooby is not defined"
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 b39e9ad74..4f738076e 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 d7bcb2908..e4cabf6ef 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 bebc1f27b..ce046e61e 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 7776c67a6..5b56ab3e7 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 07a33f766..4e62a1bc0 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 2b431dc52..2ba29dfff 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 4d805b0f7..56fb85058 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 633e1885e..1036969bb 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 3a9adc4bb..c6cab19b2 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 b0b9da0b6..f050164b6 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 3fe9faf84..edbaf8600 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 7038ab16e..f401b72d8 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 ca8abf09b..90fb7193e 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 d900c3764..570b8306c 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 e2218fffb..ab02716e3 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 bd9b3f05d..bb40f31db 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 af15b174b..2b6ade5c0 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 1cd9f462e..ec1e3e7c9 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 72b63278d..6cf3b6aef 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 4a2b3819b..1e7c170da 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 3e7538d66..8e79357b5 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 f3df52a21..1f2aeeabd 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 0dedf78c9..b84f3a1c7 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 aef2ea93d..7ba64b051 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 e25fe3893..6a79d3943 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 72d47a391..5bf6befed 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 26ddfa600..946e8b530 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 cc535e374..b02bdbe64 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 4d866acb8..24644e307 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.util/rand.util.canonical/generate_canonical.pass.cpp b/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp
index 7433e28e4..df2acbe9e 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 cb23cfa15..5140ec917 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 ae42b4666..a676e9e52 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 aac03839a..8aa71f75d 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/parse_curly_brackets.pass.cpp b/test/std/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
index d9c517230..59673ec88 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 be0c74e9c..85f38ec63 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 11982a26d..82f051a07 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 c41019542..a8ae1f550 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 4a2e6647e..6d95ad275 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.results/re.results.const/copy.pass.cpp b/test/std/re/re.results/re.results.const/copy.pass.cpp
index b9cb5b251..ab0e388b5 100644
--- a/test/std/re/re.results/re.results.const/copy.pass.cpp
+++ b/test/std/re/re.results/re.results.const/copy.pass.cpp
@@ -25,7 +25,7 @@ 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());
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
index c755b9ff0..d390d62f0 100644
--- 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
@@ -25,7 +25,7 @@ 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());
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
index de2c98c2b..2d2e81b17 100644
--- 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
@@ -26,7 +26,7 @@ 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>());
diff --git a/test/std/re/re.traits/lookup_collatename.pass.cpp b/test/std/re/re.traits/lookup_collatename.pass.cpp
index 3aeed7bdd..ef5c14257 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 57e6b753a..7563b3952 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 03b4f3985..2dd8ed247 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 33d365a9e..601da6b86 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 01f012189..e6f3d53a8 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 d74e48575..449ad8f11 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 d121e25ba..cbb03ef61 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/reserve.pass.cpp b/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
index 7210152ea..8b9dc13db 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 df1e99e01..a1f3c4b51 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 f79e43f6a..17cb7dd16 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 d9561d22b..fd9684e1f 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 9466f1135..8bc6e4fb2 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 027fbcd46..695c5e40d 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 63f86d350..22952e0f2 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 022c656e8..f14eda511 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 2b7c3c465..116da936e 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 6d66415ab..14f730b15 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 000000000..e293115fa
--- /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 000000000..d1fab485c
--- /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 000000000..5ab1c9f0b
--- /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 000000000..74d51667d
--- /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/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp
index 48da6d885..c48e3aedd 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
+++ b/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/eof.pass.cpp
@@ -6,23 +6,21 @@
// 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
-// dynarray.data
+// <string>
-// template <class Type, class Alloc>
-// struct uses_allocator<dynarray<Type>, Alloc> : true_type { };
+// template<> struct char_traits<char8_t>
+// static constexpr int_type eof();
-#include <__config>
-
-#include <experimental/dynarray>
-#include "test_allocator.h"
-
-using std::experimental::dynarray;
+#include <string>
+#include <cassert>
int main()
{
- static_assert ( std::uses_allocator<dynarray<int>, test_allocator<int>>::value, "" );
+#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 000000000..2b7d793c7
--- /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 000000000..15e645e3a
--- /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 000000000..f35816659
--- /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 000000000..f200c2332
--- /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 000000000..73c703f77
--- /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 000000000..688e55932
--- /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 000000000..274d93f13
--- /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 000000000..96159209f
--- /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 000000000..659be36ad
--- /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 000000000..64c27ffd7
--- /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 3aba1c3f1..15d971235 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/to_string.pass.cpp b/test/std/strings/string.conversions/to_string.pass.cpp
index 05e5e4b92..fdc682ce1 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 281aa1a5e..2208ec5a3 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 b21ba0422..fda67c3bf 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 3307aa61d..bab788921 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 79fadf619..0c94918b5 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 5fad2bfaa..237d1221d 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 2e9ebcb4c..70515bf48 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 53c3d261d..042e1dfab 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 b766c5168..339f1f8fd 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 b5759d701..1533b49ba 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 16a4da882..0ec838718 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 08f9e5a77..dfcb836f1 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.literals/literal.pass.cpp b/test/std/strings/string.view/string_view.literals/literal.pass.cpp
index 79fe35528..cc2202e83 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 4c29959f0..2763f7fb4 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 000000000..657a56c73
--- /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 000000000..d7014868f
--- /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
index 9374c5079..bc82ba849 100644
--- a/test/std/thread/futures/futures.async/async_race.38682.pass.cpp
+++ b/test/std/thread/futures/futures.async/async_race.38682.pass.cpp
@@ -12,7 +12,14 @@
// 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: apple-darwin
+// 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.
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 ca48eee19..8aa233f66 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 98f6c432c..16e6ff9f1 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 83271009a..79c639eb6 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 97f9d07c1..4a2db39e8 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 7f89f0af8..694e311b7 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 dcfdfd11a..f63256373 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 cb5c55925..ebaf3e6de 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/utilities/any/any.class/any.assign/copy.pass.cpp b/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
index 68de5e3d1..c148a39de 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 418f200be..19289cc39 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 f8f625263..d2e226604 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>
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 aceb9e6cf..79cac4236 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 d01a88da5..589b3c46d 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 09e9288e0..1310b6b12 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 d18de0664..83c78923d 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 789a861ee..fdd3c8334 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 2e781d954..888e3a870 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 f56a25656..9b5ab5f03 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 a5fa93218..cc118b348 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 419fd1a40..85ee8fef3 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 963852126..0e3b6a43f 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 bad229dac..cb9244990 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 2d18cf4ba..e88deafce 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 9850851fc..dad2973fb 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 c723b6e08..a2a40d138 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 b6a940f80..7b08f3047 100644
--- a/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
+++ b/test/std/utilities/charconv/charconv.from.chars/integral.pass.cpp
@@ -9,6 +9,7 @@
// 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
@@ -183,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 ab78ca464..63891b1ee 100644
--- a/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
+++ b/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp
@@ -9,6 +9,7 @@
// 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
@@ -81,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 5b660da61..ac43dd769 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 cdedf071e..ad44a04c3 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>
@@ -110,6 +110,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));
@@ -130,6 +134,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);
@@ -145,6 +153,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/refwrap/type_properties.pass.cpp b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
index 261a306ca..27d498ec8 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 000000000..a63dc5b15
--- /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 000000000..441ddf4bd
--- /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 1a812876b..1060b7343 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 12c0d0222..7a2d76c6d 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 70c5e4696..b53175376 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_to.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
index b3f3c2402..756f89429 100644
--- a/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
+++ b/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp
@@ -12,15 +12,18 @@
// 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), "");
@@ -30,4 +33,12 @@ int main()
{
(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/meta/meta.type.synop/endian.pass.cpp b/test/std/utilities/meta/meta.type.synop/endian.pass.cpp
index cf0ab2d26..865c477e7 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/meta.unary.cat/is_integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp
index 09997626e..85c2c9817 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/optional/optional.bad_optional_access/default.pass.cpp b/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
index 198eee62b..8a7308348 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 d96f70bb7..930015a73 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 98c90aa1d..bec0f09a3 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 ed8b433da..c41674f13 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 e4e4a979e..f1e9a1cfd 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 e9e98c0bd..ee0dcfd77 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 77e411b2e..000000000
--- 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 0f1fabd0c..31e7f9fdb 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 e73f3747c..cb084ecd9 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 761cbee4b..f8a98508a 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 bbc70014f..f25bf71da 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 c644fb9d6..00f934d6a 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 5347d3f55..90e8fb456 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 1a577e68b..a63e3be8e 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 000000000..3bc561cfe
--- /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 000000000..c21c85aad
--- /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 3fbf19f8e..421480aa8 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/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp
index cd1f32be2..f6dd75d24 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;
diff --git a/test/std/utilities/time/time.cal/euclidian.h b/test/std/utilities/time/time.cal/euclidian.h
index f2dc28b36..cc7e054ac 100644
--- a/test/std/utilities/time/time.cal/euclidian.h
+++ b/test/std/utilities/time/time.cal/euclidian.h
@@ -17,7 +17,7 @@ T euclidian_addition(T rhs, T lhs)
{
const T modulus = maxValue - minValue + 1;
T ret = rhs + lhs;
- if (ret > maxValue)
+ if (ret > maxValue)
ret -= modulus;
return ret;
}
@@ -31,10 +31,9 @@ T euclidian_subtraction(T lhs, T rhs)
{
const T modulus = maxValue - minValue + 1;
T ret = lhs - rhs;
- if (ret < minValue)
+ if (ret < minValue)
ret += modulus;
if (ret > maxValue) // this can happen if T is unsigned
ret += modulus;
return ret;
}
-
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
index 4aa36dd45..dd36ee574 100644
--- 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
@@ -31,13 +31,13 @@ int main()
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);
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
index a9c2a9fbf..aa084e863 100644
--- 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
@@ -39,7 +39,7 @@ int main()
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)
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
index 57fa415e1..aed46e7d7 100644
--- 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
@@ -43,7 +43,7 @@ int main()
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)
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
index 97f5abed3..1047e1bc3 100644
--- 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
@@ -30,14 +30,14 @@ int main()
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.pass.cpp b/test/std/utilities/time/time.cal/time.cal.day/time.cal.day.nonmembers/literals.pass.cpp
index 765b0e8dc..405200e47 100644
--- 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
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// UNSUPPORTED: clang-5, clang-6
+// UNSUPPORTED: clang-5, clang-6, clang-7
// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
// <chrono>
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
index 1a974cff8..47ef42c07 100644
--- 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
@@ -44,7 +44,7 @@ int main()
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};
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
index e429fea06..b08d6ef4b 100644
--- 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
@@ -44,7 +44,7 @@ int main()
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};
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
index 768918a91..9c949170a 100644
--- 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
@@ -15,31 +15,31 @@
// 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.
+//
+// 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.
+//
+// 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.
+// 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.
+// 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>
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
index ca98984e4..06b70b0aa 100644
--- 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
@@ -20,7 +20,7 @@
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
index 2dcf51fb5..5d8512058 100644
--- 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
@@ -25,7 +25,7 @@
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>, "");
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
index 1609898bb..743da74ba 100644
--- 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
@@ -19,7 +19,7 @@
// constexpr chrono::month month() const noexcept;
// constexpr chrono::day day() const noexcept;
// constexpr bool ok() const noexcept;
-
+
#include <chrono>
#include <type_traits>
#include <cassert>
@@ -34,7 +34,7 @@ int main()
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{}, "");
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
index d4b88cc01..5bc001c47 100644
--- 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
@@ -23,7 +23,6 @@
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>().day());
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
index 253218b67..d715635d4 100644
--- 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
@@ -13,7 +13,7 @@
// 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.
+// number of days in month m_; otherwise returns false.
// When m_ == February, the number of days is considered to be 29.
#include <chrono>
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
index 788e301dc..c8938be08 100644
--- 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
@@ -15,9 +15,9 @@
// 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.
+// Returns:
+// If x.month() < y.month() returns true.
+// Otherwise, if x.month() > y.month() returns false.
// Otherwise, returns x.day() < y.day().
#include <chrono>
@@ -35,19 +35,19 @@ int main()
AssertComparisons6AreNoexcept<month_day>();
AssertComparisons6ReturnBool<month_day>();
-
+
static_assert( testComparisons6(
- month_day{std::chrono::January, day{1}},
+ 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{1}},
month_day{std::chrono::January, day{2}},
false, true), "");
static_assert( testComparisons6(
- month_day{std::chrono::January, day{1}},
+ month_day{std::chrono::January, day{1}},
month_day{std::chrono::February, day{1}},
false, true), "");
@@ -55,16 +55,16 @@ int main()
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}},
+ 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}},
+ 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
index 9763a45dd..46ae31aaf 100644
--- 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
@@ -15,14 +15,14 @@
// 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.
+//
+// Effects: Streams md into os using the format specified by the NTCTS fmt.
// fmt encoding follows the rules specified in 25.11.
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
index 93ab71f43..988e43323 100644
--- 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
@@ -20,7 +20,7 @@
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
index 6733c283d..c3bc1777d 100644
--- 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
@@ -32,7 +32,7 @@ int main()
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}), "");
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
index 67ed116ae..5ae329440 100644
--- 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
@@ -17,7 +17,7 @@
//
// constexpr chrono::month month() const noexcept;
// constexpr bool ok() const noexcept;
-
+
#include <chrono>
#include <type_traits>
#include <cassert>
@@ -30,7 +30,7 @@ int main()
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(), "");
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
index f6fa346d1..3c2da00e8 100644
--- 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
@@ -15,7 +15,7 @@
// 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".
diff --git a/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp b/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp
index e87a7b277..de15cabd0 100644
--- a/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp
+++ b/test/std/utilities/time/time.cal/time.cal.mdlast/types.pass.cpp
@@ -21,7 +21,7 @@
int main()
{
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
index 274a4fb0b..5e86f58ec 100644
--- 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
@@ -31,13 +31,13 @@ int main()
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);
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
index fbfb11c09..b6d4848fb 100644
--- 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
@@ -34,13 +34,13 @@ constexpr bool testConstexpr()
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)
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
index 96996eba5..2309490ab 100644
--- 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
@@ -39,7 +39,7 @@ int main()
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)
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
index b583e99ac..1e5a045ed 100644
--- 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
@@ -42,7 +42,7 @@ int main()
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)
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
index f4e33fcf7..21c6e0027 100644
--- 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
@@ -36,11 +36,11 @@ int main()
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/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.month/time.cal.month.nonmembers/minus.pass.cpp
index e2176c9a1..1329a9f95 100644
--- 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
@@ -15,9 +15,9 @@
// 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.
+// 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 *, ...);
@@ -55,7 +55,7 @@ int main()
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};
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
index 9cc9db088..749635f81 100644
--- 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
@@ -17,9 +17,9 @@
// 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.
+// 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].
+// 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]
@@ -54,7 +54,7 @@ int main()
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};
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
index 7e133b3f9..abc2c1edc 100644
--- 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
@@ -15,28 +15,28 @@
// 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.
+//
+// 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.
+//
+// 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
+//
+// 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,
+// 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>
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
index c2a523a47..af7532c7b 100644
--- 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
@@ -20,7 +20,7 @@
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
index 75f3cd715..445b86dde 100644
--- 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
@@ -18,7 +18,7 @@
// 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>
@@ -33,7 +33,7 @@ int main()
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{}, "");
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
index 2b0127b0e..21779843a 100644
--- 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
@@ -34,12 +34,12 @@ int main()
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}},
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}},
@@ -64,23 +64,23 @@ int main()
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}},
+ 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}},
+ 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}},
+ 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
index 99d6d29b9..3858731f5 100644
--- 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
@@ -15,7 +15,7 @@
// 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>
@@ -31,6 +31,6 @@ int main()
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
index 7ca91fa6d..86479d8ca 100644
--- 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
@@ -20,7 +20,7 @@
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
index ed670de19..2dd64eb80 100644
--- 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
@@ -20,8 +20,8 @@
// 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>
@@ -39,7 +39,7 @@ int main()
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{}, "");
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
index 9758683b2..b3cd5ec2b 100644
--- 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
@@ -40,12 +40,12 @@ int main()
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}},
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{Tuesday}},
month_weekday_last{std::chrono::January, weekday_last{Wednesday}},
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
index 1a5639b4b..4e06812e0 100644
--- 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
@@ -15,7 +15,7 @@
// 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".
@@ -32,6 +32,6 @@ int main()
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
index b5e40610d..43982f4b4 100644
--- 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
@@ -21,7 +21,7 @@
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
index 5e0f37db9..146a0f180 100644
--- 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
@@ -14,19 +14,19 @@
// 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).
-//
+// 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.
@@ -46,7 +46,7 @@ int main()
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}));
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
index 428fb3eaa..f3f39c0dc 100644
--- 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
@@ -14,15 +14,15 @@
// 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.
-//
+// Returns: m / last.
+//
// constexpr month_day_last
// operator/(last_spec, int m) noexcept;
// Returns: month(m) / last.
@@ -51,7 +51,7 @@ 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;
@@ -63,7 +63,7 @@ int main()
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));
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
index 334e3da20..54b494268 100644
--- 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
@@ -54,7 +54,7 @@ int main()
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]));
@@ -67,7 +67,7 @@ int main()
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)
@@ -82,7 +82,7 @@ int main()
assert(mwd2.weekday_indexed() == wdi);
assert(mwd1 == mwd2);
}
- }
+ }
{ // operator/(int m, const weekday_indexed& wdi) (and switched)
@@ -97,7 +97,7 @@ int main()
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)
@@ -111,5 +111,5 @@ int main()
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
index 9a103fe18..516e0f182 100644
--- 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
@@ -14,15 +14,15 @@
// 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.
@@ -48,7 +48,7 @@ int main()
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]));
@@ -61,7 +61,7 @@ int main()
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)
{
@@ -90,7 +90,7 @@ int main()
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)
{
@@ -103,5 +103,5 @@ int main()
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
index efe0560ad..62e1c3ace 100644
--- 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
@@ -13,7 +13,7 @@
// 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).
@@ -56,7 +56,7 @@ int main()
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)
{
@@ -64,5 +64,5 @@ int main()
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
index 9cbe7df5b..d2dfc1321 100644
--- 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
@@ -14,23 +14,23 @@
// 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.
@@ -51,7 +51,6 @@ int main()
using year_month = std::chrono::year_month;
using month_day = std::chrono::month_day;
using year_month_day = std::chrono::year_month_day;
- using weekday = std::chrono::weekday;
constexpr month February = std::chrono::February;
constexpr year_month Feb2018{year{2018}, February};
@@ -62,7 +61,7 @@ int main()
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)
@@ -85,7 +84,7 @@ int main()
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)
@@ -108,7 +107,7 @@ int main()
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)
@@ -137,7 +136,7 @@ int main()
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)
@@ -168,7 +167,7 @@ int main()
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)
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
index e4a95cb92..dc884638d 100644
--- 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
@@ -18,15 +18,15 @@
// 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.
@@ -41,22 +41,18 @@
int main()
{
- using month_weekday = std::chrono::month_weekday;
using month = std::chrono::month;
using year_month = std::chrono::year_month;
using year = std::chrono::year;
- using weekday_last = std::chrono::weekday_last;
- using weekday = std::chrono::weekday;
- using month_weekday_last = std::chrono::month_weekday_last;
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));
@@ -66,7 +62,7 @@ int main()
for (int i = 1000; i < 1010; ++i)
for (unsigned j = 1; j <= 12; ++j)
{
- year y{i};
+ year y{i};
month m{j};
year_month_day_last ymdl = year_month{y,m}/last;
assert(ymdl.year() == y);
@@ -85,11 +81,11 @@ int main()
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};
+ 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;
@@ -99,7 +95,7 @@ int main()
assert(ymdl1.year() == y);
assert(ymdl1 == ymdl2);
}
- }
+ }
{ // operator/(int y, const month_day_last& mdl) (and switched)
ASSERT_NOEXCEPT ( 2018/month_day_last{February});
@@ -111,11 +107,11 @@ int main()
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};
+ 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;
@@ -125,5 +121,5 @@ int main()
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
index 5a7885712..56d88ca7c 100644
--- 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
@@ -14,19 +14,19 @@
// 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.
@@ -52,10 +52,10 @@ int main()
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}));
@@ -141,5 +141,5 @@ int main()
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
index 6b2a213b8..84ea86c22 100644
--- 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
@@ -14,19 +14,19 @@
// 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.
@@ -43,7 +43,6 @@
int main()
{
using year_month = std::chrono::year_month;
- using month_weekday = std::chrono::month_weekday;
using year = std::chrono::year;
using month = std::chrono::month;
using weekday = std::chrono::weekday;
@@ -53,7 +52,7 @@ int main()
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};
@@ -63,7 +62,7 @@ int main()
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)
@@ -81,7 +80,7 @@ int main()
{ // 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});
@@ -118,7 +117,7 @@ int main()
{ // 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);
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
index f8db3d5d8..7a9cfd2d6 100644
--- 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
@@ -20,7 +20,7 @@
// constexpr chrono::weekday weekday() const noexcept;
// constexpr unsigned index() const noexcept;
// constexpr bool ok() const noexcept;
-
+
#include <chrono>
#include <type_traits>
#include <cassert>
@@ -34,7 +34,7 @@ int main()
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, "");
@@ -44,7 +44,7 @@ int main()
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);
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
index 220e290b9..2381322fa 100644
--- 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
@@ -30,13 +30,13 @@ int main()
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}), "");
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
index 7e1dcbcf1..0e5f77dd7 100644
--- 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
@@ -16,8 +16,8 @@
// 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 ']',
+// 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]".
@@ -31,6 +31,6 @@ 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
index b64a66ae7..a21ae0dc5 100644
--- 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
@@ -20,7 +20,7 @@
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
index c15397fc5..1ea5196ad 100644
--- 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
@@ -30,7 +30,7 @@ int main()
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(), "");
@@ -38,7 +38,7 @@ int main()
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}};
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
index a5671f725..59ab4da08 100644
--- 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
@@ -29,14 +29,14 @@ int main()
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
index 0d2275c09..65d0eed4a 100644
--- 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
@@ -15,7 +15,7 @@
// 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>
@@ -29,6 +29,6 @@ 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
index 1052429da..f6c191329 100644
--- 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
@@ -20,7 +20,7 @@
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 000000000..235138235
--- /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
index ad34ae032..f6bfc2192 100644
--- 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
@@ -34,13 +34,13 @@ int main()
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);
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 000000000..c49d05d3a
--- /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
index 5a7e7971e..74774b6a0 100644
--- 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
@@ -40,7 +40,7 @@ int main()
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)
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
index 3d7685aae..945d97f49 100644
--- 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
@@ -40,7 +40,7 @@ int main()
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)
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
index 23b5f1435..1498d2748 100644
--- 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
@@ -13,8 +13,8 @@
// constexpr weekday_indexed operator[](unsigned index) const noexcept;
// constexpr weekday_last operator[](last_spec) const noexcept;
-
-
+
+
#include <chrono>
#include <type_traits>
#include <cassert>
@@ -35,7 +35,7 @@ int main()
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, "");
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
index 2462a8728..27c14a55a 100644
--- 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
@@ -44,7 +44,7 @@ int main()
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)
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
index 041706f66..0142feee8 100644
--- 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
@@ -28,14 +28,14 @@ int main()
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/minus.pass.cpp b/test/std/utilities/time/time.cal/time.cal.weekday/time.cal.weekday.nonmembers/minus.pass.cpp
index df15cf242..ca126e9dc 100644
--- 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
@@ -16,7 +16,7 @@
//
// 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.
+// [days{0}, days{6}] satisfying y + d == x.
// Otherwise the value returned is unspecified.
// [Example: Sunday - Monday == days{6}. —end example]
@@ -55,7 +55,7 @@ int main()
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)
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
index 43f2a0f09..bb9145a65 100644
--- 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
@@ -17,9 +17,9 @@
// 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.
+// 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].
+// 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]
@@ -55,7 +55,7 @@ int main()
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)
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
index fd6e3d3b6..cf28397a3 100644
--- 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
@@ -15,23 +15,23 @@
// 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.
+//
+// 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.
+//
+// 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)
@@ -51,6 +51,6 @@
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
index fb6515d20..0a3a89406 100644
--- 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
@@ -20,7 +20,7 @@
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
index a4e6c3a36..904e722db 100644
--- 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
@@ -31,13 +31,13 @@ int main()
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);
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
index 0fe4d08fd..810b28d9b 100644
--- 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
@@ -39,7 +39,7 @@ int main()
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)
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
index decd8358a..a6b60d6a0 100644
--- 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
@@ -39,7 +39,7 @@ int main()
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)
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
index fa05ef5ae..c74b5f801 100644
--- 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
@@ -32,14 +32,13 @@ constexpr bool testConstexpr()
int main()
{
using year = std::chrono::year;
- using years = std::chrono::years;
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)
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
index a3e065ffc..b457b7e91 100644
--- 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
@@ -43,7 +43,7 @@ int main()
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)
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
index 8c722e66c..70bf9e11a 100644
--- 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
@@ -33,14 +33,14 @@ int main()
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.pass.cpp b/test/std/utilities/time/time.cal/time.cal.year/time.cal.year.nonmembers/literals.pass.cpp
index 7972e4e94..0661567d8 100644
--- 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
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// UNSUPPORTED: clang-5, clang-6
+// UNSUPPORTED: clang-5, clang-6, clang-7
// UNSUPPORTED: apple-clang-6, apple-clang-7, apple-clang-8, apple-clang-9, apple-clang-10
// <chrono>
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
index 15ea8b2fb..04cf9f617 100644
--- 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
@@ -15,9 +15,9 @@
// 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.
+// 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 *, ...);
@@ -48,7 +48,7 @@ int main()
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};
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
index b975d0688..4bc92df21 100644
--- 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
@@ -15,28 +15,28 @@
// 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.
+//
+// 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.
+//
+// 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
+// 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.
@@ -50,6 +50,6 @@
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
index ca5ffc650..92094b0c2 100644
--- 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
@@ -20,7 +20,7 @@
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
index cd420f0b6..4a1cc9087 100644
--- 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
@@ -34,7 +34,7 @@ int main()
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{}, "");
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
index 5de3043db..44648c4a0 100644
--- 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
@@ -45,7 +45,7 @@ int main()
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)
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
index cab369d7b..073a28656 100644
--- 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
@@ -46,7 +46,7 @@ int main()
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)
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
index a2a77c882..d0c8d1e8c 100644
--- 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
@@ -15,9 +15,9 @@
// 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.
+// Returns:
+// If x.year() < y.year() returns true.
+// Otherwise, if x.year() > y.year() returns false.
// Otherwise, returns x.month() < y.month().
#include <chrono>
@@ -35,19 +35,19 @@ int main()
AssertComparisons6AreNoexcept<year_month>();
AssertComparisons6ReturnBool<year_month>();
-
+
static_assert( testComparisons6(
- year_month{year{1234}, std::chrono::January},
+ 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::January},
year_month{year{1234}, std::chrono::February},
false, true), "");
static_assert( testComparisons6(
- year_month{year{1234}, std::chrono::January},
+ year_month{year{1234}, std::chrono::January},
year_month{year{1235}, std::chrono::January},
false, true), "");
@@ -55,15 +55,15 @@ int main()
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}},
+ 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{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
index a8d1e7492..1f77811ac 100644
--- 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
@@ -12,11 +12,11 @@
// class year_month;
// constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
-// Returns: ym + -dy.
-//
+// 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()})}
@@ -41,7 +41,7 @@ int main()
{ // 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};
@@ -56,7 +56,7 @@ int main()
{ // 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};
@@ -71,7 +71,7 @@ int main()
{ // 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
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
index 6d42e9e67..67616764d 100644
--- 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
@@ -13,14 +13,14 @@
// 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.
+// 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.
@@ -66,7 +66,7 @@ int main()
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};
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
index 8ec8672f9..8679c9612 100644
--- 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
@@ -15,27 +15,27 @@
// 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
+//
+// 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
+// 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.
@@ -52,6 +52,6 @@ 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
index 298c2edef..200e2874d 100644
--- 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
@@ -20,7 +20,7 @@
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
index 520aaf3bc..5c7de1418 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day;
@@ -15,7 +14,7 @@
// explicit constexpr year_month_day(const local_days& dp) noexcept;
//
//
-// Effects: Constructs an object of type year_month_day that corresponds
+// 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()}.
@@ -34,11 +33,53 @@
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 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<const local_days>()});
- assert(false);
+ 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
index be3970ec1..e2e0ac38c 100644
--- 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
@@ -38,9 +38,9 @@ int main()
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{}, "");
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
index 66a19ca33..36a6c7d18 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day;
@@ -15,9 +14,9 @@
// 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
+// to the date represented by dp.
//
-// Remarks: For any value ymd of type year_month_day for which ymd.ok() is true,
+// 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;
@@ -33,12 +32,53 @@
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 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<const sys_days>()});
- assert(false);
+ 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
index 4129864e1..a8d6526b3 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day;
@@ -33,10 +32,49 @@ int main()
using year = std::chrono::year;
using month = std::chrono::month;
using day = std::chrono::day;
-// using year_month_day_last = std::chrono::year_month_day_last;
+ 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>()});
- assert(false);
-
+ 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/ok.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymd/time.cal.ymd.members/ok.pass.cpp
index 529d0d760..cab0599b9 100644
--- 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
@@ -44,6 +44,37 @@ int main()
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}};
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 000000000..a70fe30fc
--- /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 000000000..4e263bccc
--- /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
index d831f94a9..7cd31222d 100644
--- 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
@@ -46,7 +46,7 @@ int main()
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)
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
index 39bdc7c21..650941dc9 100644
--- 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
@@ -46,7 +46,7 @@ int main()
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)
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
index bad421b6c..0df684395 100644
--- 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
@@ -15,9 +15,9 @@
// 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.
+// 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()
@@ -39,21 +39,21 @@ int main()
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}},
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{1}},
year_month_day{year{1234}, January, day{2}},
false, true), "");
-
+
// different month
static_assert( testComparisons6(
year_month_day{year{1234}, January, day{1}},
@@ -96,23 +96,23 @@ int main()
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}},
+ 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}},
+ 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{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
index e3641ff02..41b61f7b6 100644
--- 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
@@ -12,7 +12,7 @@
// class year_month_day;
// constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
-// Returns: ymd + (-dy)
+// Returns: ymd + (-dy)
#include <chrono>
@@ -48,7 +48,7 @@ int main()
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)
{
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
index d5f227631..c325d1f89 100644
--- 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
@@ -13,14 +13,14 @@
// 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.
@@ -91,7 +91,7 @@ int main()
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}};
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
index 72693f8d4..4bfca1549 100644
--- 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
@@ -15,27 +15,27 @@
// 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
+//
+// 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
+// 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.
@@ -53,6 +53,6 @@ int main()
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
index 90e9c1834..f13f4da1a 100644
--- 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
@@ -20,7 +20,7 @@
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
index 3be621cdd..e2a6a7acf 100644
--- 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
@@ -32,12 +32,11 @@ 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(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{}}};
@@ -45,7 +44,7 @@ int main()
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, "");
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
index 7eac6e5ea..db3369c6c 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day_last;
@@ -29,15 +28,24 @@ int main()
using month_day_last = std::chrono::month_day_last;
using year_month_day_last = std::chrono::year_month_day_last;
-// TODO: wait for calendar
-// ASSERT_NOEXCEPT( std::declval<const year_month_day_last>().day());
-// ASSERT_SAME_TYPE(day, decltype(std::declval<const year_month_day_last>().day()));
-//
-// static_assert( year_month_day_last{}.day() == day{}, "");
-
- for (unsigned i = 1; i <= 12; ++i)
- {
- year_month_day_last ymd(year{1234}, month_day_last{month{i}});
- assert( static_cast<unsigned>(ymd.day()) == i);
- }
+ 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
index a689394f1..43ec42d94 100644
--- 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
@@ -24,7 +24,6 @@ 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;
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
index 2acfc5c21..613cc1c6b 100644
--- 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
@@ -24,7 +24,6 @@ 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;
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
index acff45b6e..7b61214b7 100644
--- 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
@@ -24,7 +24,6 @@ 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;
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
index 43a3ef203..45f1ac4ae 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day_last;
@@ -24,13 +23,39 @@
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 sys_days = std::chrono::local_days;
+ 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>().year()));
-// ASSERT_SAME_TYPE(year, decltype(static_cast<local_days>(std::declval<const year_month_day_last>().year()));
- assert(false);
+ 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
index 8c1b3131e..20aff6d1d 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day_last;
@@ -24,13 +23,39 @@
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 sys_days = std::chrono::sys_days;
+ 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>().year()));
-// ASSERT_SAME_TYPE(year, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>().year()));
- assert(false);
+ 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
index 455b9f919..bfa1d58d9 100644
--- 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
@@ -37,7 +37,6 @@ 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 months = std::chrono::months;
@@ -47,7 +46,7 @@ int main()
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)
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
index 6dbec39c3..ce364d236 100644
--- 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
@@ -37,7 +37,6 @@ 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 years = std::chrono::years;
@@ -47,7 +46,7 @@ int main()
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)
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
index 3e4f1cd03..0f4da09dc 100644
--- 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
@@ -24,7 +24,6 @@ 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;
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
index 2c9776b3c..d4e4a1185 100644
--- 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
@@ -15,8 +15,8 @@
// 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.
+// 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()
@@ -31,21 +31,20 @@ 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;
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}},
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}},
@@ -74,15 +73,15 @@ int main()
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}}},
+ 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{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
index 3e41215bd..1c8d4e7af 100644
--- 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
@@ -13,12 +13,12 @@
// 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).
@@ -52,7 +52,6 @@ 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 months = std::chrono::months;
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
index b441ec0fe..25ab85d8f 100644
--- 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
@@ -15,22 +15,22 @@
// 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
+// 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
+// Returns: ymdl + dy
@@ -68,7 +68,6 @@ 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 months = std::chrono::months;
@@ -104,7 +103,7 @@ int main()
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}};
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
index 230ae04ce..06c752e29 100644
--- 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
@@ -15,7 +15,7 @@
// 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().
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
index 809ec0133..a0b98abb7 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_weekday;
@@ -15,7 +14,7 @@
// explicit constexpr year_month_weekday(const local_days& dp) noexcept;
//
//
-// Effects: Constructs an object of type year_month_weekday that corresponds
+// 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()}.
@@ -33,12 +32,64 @@
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 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>()});
- assert(false);
+ 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
index 8e313fb02..751de6091 100644
--- 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
@@ -35,7 +35,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
@@ -45,7 +44,7 @@ int main()
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{}, "");
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
index 63ea496d6..b9d3b6c62 100644
--- 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
@@ -7,17 +7,16 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <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
+// 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,
+// 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;
@@ -32,12 +31,64 @@
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 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>()});
- assert(false);
+ 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/ctor.year_month_day_last.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp
deleted file mode 100644
index b873a1956..000000000
--- a/test/std/utilities/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/ctor.year_month_day_last.pass.cpp
+++ /dev/null
@@ -1,41 +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, c++17
-// XFAIL: *
-
-// <chrono>
-// class year_month_weekday;
-
-// constexpr year_month_weekday(const year_month_weekday_last& ymdl) noexcept;
-//
-// Effects: Constructs an object of type year_month_weekday 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 year_month_weekday_last = std::chrono::year_month_weekday_last;
- using year_month_weekday = std::chrono::year_month_weekday;
-
- ASSERT_NOEXCEPT(year_month_weekday{std::declval<const year_month_weekday_last>()});
-
-}
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
index 7d6a04b85..5a29b8218 100644
--- 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
@@ -24,7 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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
index 13122e087..5749da9af 100644
--- 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
@@ -24,8 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
- using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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
index cb669f807..97f898986 100644
--- 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
@@ -24,7 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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 000000000..ef30ce526
--- /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 000000000..04986e50d
--- /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
index 2007454ca..c5e101250 100644
--- 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
@@ -37,11 +37,9 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
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;
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
index 315dd45c1..86830249e 100644
--- 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
@@ -37,19 +37,17 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
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;
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;
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
index e52255d3d..ad9bc6ee6 100644
--- 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
@@ -24,7 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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
index 963112b4a..52d918e55 100644
--- 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
@@ -24,7 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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
index 55b549d51..5cf1cbaf7 100644
--- 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
@@ -24,8 +24,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
- using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
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
index a930dd991..fc13709cd 100644
--- 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
@@ -27,29 +27,28 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
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}},
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, 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}},
@@ -95,7 +94,7 @@ int main()
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)
@@ -103,7 +102,7 @@ int main()
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)
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
index 6f0d22ec6..0b217414c 100644
--- 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
@@ -13,7 +13,7 @@
// 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).
@@ -55,7 +55,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
@@ -70,7 +69,7 @@ int main()
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)
{
@@ -81,13 +80,13 @@ int main()
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)
{
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
index a6a748614..50572c0c4 100644
--- 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
@@ -13,14 +13,14 @@
// 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.
@@ -56,7 +56,6 @@ int main()
{
using year = std::chrono::year;
using month = std::chrono::month;
- using day = std::chrono::day;
using weekday = std::chrono::weekday;
using weekday_indexed = std::chrono::weekday_indexed;
using year_month_weekday = std::chrono::year_month_weekday;
@@ -98,7 +97,7 @@ int main()
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}};
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
index ff6ce35e1..f985f46ea 100644
--- 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
@@ -15,27 +15,27 @@
// 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
+//
+// 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
+// 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.
@@ -52,6 +52,6 @@ int main()
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
index 2343d9db4..8969bd32a 100644
--- 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
@@ -20,7 +20,7 @@
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
index 4359ea9a8..cd3f112ac 100644
--- 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
@@ -41,7 +41,7 @@ int main()
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, "");
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
index 56009c422..45f1ac4ae 100644
--- 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
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
// class year_month_day_last;
@@ -24,12 +23,39 @@
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 sys_days = std::chrono::local_days;
+ 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>().year()));
- ASSERT_SAME_TYPE(year, decltype(static_cast<local_days>(std::declval<const year_month_day_last>().year()));
+ 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
index 47beca7d9..c5abe4ace 100644
--- 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
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
-// XFAIL: *
// <chrono>
-// class year_month_day_last;
+// class year_month_weekday_last;
// constexpr operator sys_days() const noexcept;
-// Returns: sys_days{year()/month()/day()}.
+// 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>
@@ -21,16 +21,49 @@
#include "test_macros.h"
+#include <iostream>
+
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 sys_days = std::chrono::sys_days;
+ 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}, "");
+ }
- ASSERT_NOEXCEPT( static_cast<sys_days>(std::declval<const year_month_day_last>().year()));
- ASSERT_SAME_TYPE(year, decltype(static_cast<sys_days>(std::declval<const year_month_day_last>().year()));
+ { // 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_year.pass.cpp b/test/std/utilities/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.members/plus_minus_equal_year.pass.cpp
index 47a888499..8793c659a 100644
--- 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
@@ -47,7 +47,7 @@ int main()
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;
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
index 0c8becd45..6af54892a 100644
--- 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
@@ -33,23 +33,23 @@ int main()
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}},
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{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}},
@@ -95,7 +95,7 @@ int main()
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)
@@ -103,7 +103,7 @@ int main()
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)
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
index a53fa7ebf..c0ca34e83 100644
--- 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
@@ -13,7 +13,7 @@
// 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).
@@ -71,7 +71,7 @@ int main()
assert(ym1.weekday_last() == weekday_last{Tuesday});
}
}
-
+
{ // year_month_weekday_last - months
ASSERT_NOEXCEPT( std::declval<year_month_weekday_last>() - std::declval<months>());
@@ -89,5 +89,5 @@ int main()
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
index e79262e0d..9f8eb9dc0 100644
--- 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
@@ -13,13 +13,13 @@
// 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.
@@ -93,7 +93,7 @@ int main()
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}};
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
index 08c0c1d64..46b6ebaed 100644
--- 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
@@ -15,7 +15,7 @@
// 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().
@@ -33,6 +33,6 @@ int main()
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
index 4ce47f05d..a7f3f024e 100644
--- 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
@@ -20,7 +20,7 @@
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 000000000..0b5757f67
--- /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 000000000..955e3ebe9
--- /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 000000000..69dfa9180
--- /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 000000000..c0fa0b5be
--- /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 2f8a707bf..47a610f00 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 4458d6f21..e5e6de260 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 deb4615fa..c5ecb3227 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 000000000..9f91ca744
--- /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 000000000..299e06818
--- /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.nonmember/op_divide_duration.pass.cpp b/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_duration.pass.cpp
index 561516b66..4c4895b2a 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 48c3e86e8..275f87760 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 0d94aaa58..daf7165cf 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 7b312c5ac..a43bb099f 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 5d616418c..d60f6276a 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
@@ -39,7 +39,7 @@ int main()
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 44d5d4110..9ef952559 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
@@ -39,7 +39,7 @@ int main()
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 6bba6fc82..85447ea41 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 b1d955c25..fab5b4aae 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 e3754c1f6..bd4115437 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 508837375..207a9ab5a 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 b84a67673..614c69b2e 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/tuple/tuple.tuple/TupleFunction.pass.cpp b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp
index ce6dcf811..977d2b6da 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 210f14be3..9bc0ef501 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 457df5602..bfa7c0d23 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 818001833..05ff8a4df 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 ccdd48e4c..c4f2e52ab 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 03fb78caa..a18b9fc89 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 c5ffacfa3..14bf08412 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 c738adad7..aa86949dd 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 5b0f15ecb..4e76e12b9 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 f52dc5556..dd76fa6c7 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 0a2222cbf..7b4a67048 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.variant/variant.assign/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
index 29228e562..6c8a2b86a 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 068b9a201..5ea7069f5 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 c410b4b8f..cee141a8c 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 3f7cd4f0b..d414c3503 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 1696f9cc2..6eeec69c8 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 05a09db45..e4278f0e0 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 af6c66213..0e1ba7bba 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 9d0bf55fb..7dcd2541b 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 ec2730e87..c798efbaa 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 e151572c4..7d632af9a 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 6b392068d..f59367109 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 20848db0f..d281927c7 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 28a0c5828..939e8f39d 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 923ffd33a..4fed14167 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 c01d33344..f03e95644 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 7ab828eb0..6d78de3a4 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,18 @@
#include "test_macros.h"
#include "variant_test_helpers.hpp"
+
int main() {
-#if TEST_STD_VER == 17
- { // This test does not pass on C++20 or later; see https://bugs.llvm.org/show_bug.cgi?id=39232
- using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ {
+ using V = std::variant<int, long>;
constexpr V v;
static_assert(v.index() == 0, "");
}
-#endif
+ {
+ 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>);
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 be021917d..9ccdc2221 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,14 +25,18 @@
#include "test_macros.h"
#include "variant_test_helpers.hpp"
+
int main() {
-#if TEST_STD_VER == 17
- { // This test does not pass on C++20 or later; see https://bugs.llvm.org/show_bug.cgi?id=39232
- using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ {
+ using V = std::variant<int, long>;
constexpr V v;
static_assert(!v.valueless_by_exception(), "");
}
-#endif
+ {
+ 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");
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 b81b3ff6a..ec85ce767 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 c0db96793..693369abb 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 afc85c97f..ec8654d19 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 533f5869b..a0ea7c3ce 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 360450179..943dcf9f5 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 050b51b75..a0b3ca518 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 081e678b6..078958274 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/min_allocator.h b/test/support/min_allocator.h
index a3af9e1db..454749397 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 97a17bb68..3c2a5e27a 100644
--- a/test/support/nasty_macros.hpp
+++ b/test/support/nasty_macros.hpp
@@ -49,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 6f42ebf8b..07cb72692 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 1d3158091..f67a84fa2 100644
--- a/test/support/test_comparisons.h
+++ b/test/support/test_comparisons.h
@@ -81,7 +81,7 @@ 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);
}
@@ -146,7 +146,7 @@ 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);
}
diff --git a/test/support/truncate_fp.h b/test/support/truncate_fp.h
new file mode 100644
index 000000000..83b2b2cff
--- /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 6fb9eaa24..18c8f780b 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 000000000..1f01fa397
--- /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 000000000..b365cc6d8
--- /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 000000000..0d2d6d313
--- /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 000000000..8dc43f401
--- /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 000000000..85feb16ac
--- /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 000000000..6f19a96a1
--- /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 000000000..222700229
--- /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 000000000..f47ddcd24
--- /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 000000000..fabee0e81
--- /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 000000000..45f5a1cf6
--- /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 000000000..4b3f13fa5
--- /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 3c1b4f218..8c30e28f5 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 000000000..a591743c6
--- /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 000000000..4625dfb08
--- /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 000000000..5649ddcc7
--- /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 daea1f66f..09e2e0551 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 8ddacabb6..310c7ee9f 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 2ff2f2a8f..ee74ff886 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 80e69f6e1..858ea2334 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 000000000..54734f1ea
--- /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 000000000..cf240190b
--- /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 c4c4d660f..99b56dd62 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 88cebe3a1..4f10f226d 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 7ce1a633d..b9c14436d 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 70500bd32..4a3b2e9bd 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 193fffc4b..a0fd7c6e1 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 000000000..706ad559d
--- /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 b14bc6291..aab07500a 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 000000000..8d3108363
--- /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 dd7a3ffe8..0524a85c0 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 26a89721c..f17f5b223 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 000000000..38faeec8e
--- /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 000000000..96e8282a1
--- /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 2dec4a8b2..fff6a9881 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 aafd538df..6ef17660c 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 48920ca78..ca364727c 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 4a641909d..d2f1d27eb 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 00d576416..f5e37b011 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 b7e9203ff..5dbf4fd27 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 611605af6..7d01e8e4e 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 541661a25..59bc5f710 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 54aa04a42..1512ac90f 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 612dda2d1..e821aec18 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 4a5501273..fc5f8b030 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 73064b97b..c0c07e5e6 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 82b4d72b6..6e274c7ea 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 2010e2450..7613ff92c 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 000000000..3d078586f
--- /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 f49ca5148..f15ce2081 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 5f9166089..323ddfe7a 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 000000000..3c36d3f03
--- /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 000000000..94be60837
--- /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 31a919991..9385761b2 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 394c4f5d1..5dc951d2b 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 18de6d68e..3ac5b21fb 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 000000000..9646b9be5
--- /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 1662fcb8b..ec6d51b35 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 39785fb7f..06579772f 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 4c81734cf..2c5d073f6 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 4f126b6d9..030e98916 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 7f7ccb9f7..bb0d6b4c5 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 000000000..fa0ef9720
--- /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 d27e24b34..539ace6fb 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 100755
index 7bbf0d015..000000000
--- 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 ca793f336..49f8b0614 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 e5cf50c74..acc5ba17a 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 4d03a5476..5085b9319 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 07c237727..1f8e8e2c4 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 f63c41dfd..1aa52ddbb 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 https://libcxx.llvm.org/docs/DesignDocs/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 explicitly 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')
@@ -745,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)
@@ -931,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 a3fa535e2..6a334ac31 100644
--- a/utils/libcxx/test/format.py
+++ b/utils/libcxx/test/format.py
@@ -206,7 +206,7 @@ class LibcxxTestFormat(object):
cmd, out, err, rc = self.executor.run(exec_path, [exec_path],
local_cwd, data_files,
env)
- report = "Compiled With: %s\n" % compile_cmd
+ 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
diff --git a/utils/libcxx/test/googlebenchmark.py b/utils/libcxx/test/googlebenchmark.py
new file mode 100644
index 000000000..6fe731e8c
--- /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 de2232ff4..32bbb2e11 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)
@@ -279,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/cxx2a_status.html b/www/cxx2a_status.html
index 97f5a8d5a..a5e87ec18 100644
--- a/www/cxx2a_status.html
+++ b/www/cxx2a_status.html
@@ -80,7 +80,7 @@
<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>
@@ -107,6 +107,37 @@
<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>
@@ -219,10 +250,48 @@
<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: 12-Sep-2018</p>
+ <p>Last Updated: 28-Nov-2018</p>
</div>
</body>
</html>