summaryrefslogtreecommitdiff
path: root/test/std/utilities
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:58 +0000
commit53a420fba21cf1644972b34dcd811a43cdb8368d (patch)
tree66a19f6f8b65215772549a51d688492ab8addc0d /test/std/utilities
parentb50f1549701eb950921e5d6f2e55ba1a1dadbb43 (diff)
Notes
Diffstat (limited to 'test/std/utilities')
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp6
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp6
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp9
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp139
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp155
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp156
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp155
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp147
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp139
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp4
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp6
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp7
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp5
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp6
-rw-r--r--test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp4
-rw-r--r--test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp6
-rw-r--r--test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp4
-rw-r--r--test/std/utilities/allocator.adaptor/types.pass.cpp6
-rw-r--r--test/std/utilities/any/any.class/any.assign/copy.pass.cpp197
-rw-r--r--test/std/utilities/any/any.class/any.assign/move.pass.cpp108
-rw-r--r--test/std/utilities/any/any.class/any.assign/value.pass.cpp209
-rw-r--r--test/std/utilities/any/any.class/any.cons/copy.pass.cpp100
-rw-r--r--test/std/utilities/any/any.class/any.cons/default.pass.cpp47
-rw-r--r--test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp194
-rw-r--r--test/std/utilities/any/any.class/any.cons/move.pass.cpp104
-rw-r--r--test/std/utilities/any/any.class/any.cons/value.pass.cpp154
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp262
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp63
-rw-r--r--test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp133
-rw-r--r--test/std/utilities/any/any.class/any.observers/has_value.pass.cpp64
-rw-r--r--test/std/utilities/any/any.class/any.observers/type.pass.cpp41
-rw-r--r--test/std/utilities/any/any.class/not_literal_type.pass.cpp21
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp171
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp313
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp66
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp46
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp58
-rw-r--r--test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp37
-rw-r--r--test/std/utilities/any/any.nonmembers/make_any.pass.cpp140
-rw-r--r--test/std/utilities/any/any.nonmembers/swap.pass.cpp40
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp8
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp2
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp2
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp26
-rw-r--r--test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp6
-rw-r--r--test/std/utilities/function.objects/func.invoke/invoke_feature_test_macro.pass.cpp39
-rw-r--r--test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp28
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.fail.cpp25
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.pass.cpp29
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp15
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp21
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp21
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.fail.cpp25
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp3
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.fail.cpp29
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp24
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.fail.cpp30
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp1
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.fail.cpp27
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp3
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.fail.cpp60
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp3
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp119
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp175
-rw-r--r--test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/refwrap/type_properties.pass.cpp6
-rw-r--r--test/std/utilities/function.objects/unord.hash/enum.pass.cpp7
-rw-r--r--test/std/utilities/function.objects/unord.hash/integral.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/unord.hash/non_enum.pass.cpp38
-rw-r--r--test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp6
-rw-r--r--test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp3
-rw-r--r--test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp3
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp5
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp17
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp10
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp5
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp6
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp20
-rw-r--r--test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp6
-rw-r--r--test/std/utilities/memory/allocator.traits/rebind_traits.pass.cpp8
-rw-r--r--test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp38
-rw-r--r--test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp34
-rw-r--r--test/std/utilities/memory/default.allocator/allocator_types.pass.cpp4
-rw-r--r--test/std/utilities/memory/pointer.traits/rebind.pass.cpp4
-rw-r--r--test/std/utilities/memory/specialized.algorithms/specialized.addressof/addressof.temp.fail.cpp (renamed from test/std/utilities/utility/forward/forward3.fail.cpp)18
-rw-r--r--test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp2
-rw-r--r--test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp47
-rw-r--r--test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp78
-rw-r--r--test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp49
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp112
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp116
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp111
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp115
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp13
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp13
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp13
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp13
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp114
-rw-r--r--test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp117
-rw-r--r--test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp3
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp1
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.runtime/null_ctor.pass.cpp11
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp6
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp2
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert08.fail.cpp42
-rw-r--r--test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert11.fail.cpp42
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp4
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp4
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp2
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp2
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp2
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp2
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp2
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp16
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp16
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp3
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp7
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp3
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp6
-rw-r--r--test/std/utilities/meta/meta.help/integral_constant.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.arr/remove_all_extents.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.arr/remove_extent.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/add_const.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/add_cv.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/add_volatile.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/remove_const.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/remove_cv.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.cv/remove_volatile.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp20
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp209
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/conditional.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/decay.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/enable_if.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp13
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp11
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.sign/make_signed.pass.cpp8
-rw-r--r--test/std/utilities/meta/meta.trans/meta.trans.sign/make_unsigned.pass.cpp8
-rw-r--r--test/std/utilities/meta/meta.unary.prop.query/void_t_feature_test_macro.pass.cpp36
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.comp/rvalue_ref.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp7
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp193
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp4
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp20
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp36
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp2
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp2
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp2
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp9
-rw-r--r--test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp2
-rw-r--r--test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp (renamed from test/std/utilities/utility/forward/forward2.fail.cpp)16
-rw-r--r--test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp25
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp53
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp55
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp55
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp55
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp55
-rw-r--r--test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp53
-rw-r--r--test/std/utilities/optional/optional.hash/hash.pass.cpp48
-rw-r--r--test/std/utilities/optional/optional.nullops/equal.pass.cpp39
-rw-r--r--test/std/utilities/optional/optional.nullops/greater.pass.cpp39
-rw-r--r--test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp39
-rw-r--r--test/std/utilities/optional/optional.nullops/less_equal.pass.cpp40
-rw-r--r--test/std/utilities/optional/optional.nullops/less_than.pass.cpp39
-rw-r--r--test/std/utilities/optional/optional.nullops/not_equal.pass.cpp39
-rw-r--r--test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp25
-rw-r--r--test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp38
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp273
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp254
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp102
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp237
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp113
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp174
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp67
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp268
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp143
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp128
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp134
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp155
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp81
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp121
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp84
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp148
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp116
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp201
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp73
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp93
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp153
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp68
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp61
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp37
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp73
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp69
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp69
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp73
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp37
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp72
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp76
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp73
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp33
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp64
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp64
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp68
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp77
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp72
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp306
-rw-r--r--test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp50
-rw-r--r--test/std/utilities/optional/optional.object/special_member_gen.pass.cpp74
-rw-r--r--test/std/utilities/optional/optional.object/types.pass.cpp38
-rw-r--r--test/std/utilities/optional/optional.relops/equal.pass.cpp74
-rw-r--r--test/std/utilities/optional/optional.relops/greater_equal.pass.cpp70
-rw-r--r--test/std/utilities/optional/optional.relops/greater_than.pass.cpp70
-rw-r--r--test/std/utilities/optional/optional.relops/less_equal.pass.cpp70
-rw-r--r--test/std/utilities/optional/optional.relops/less_than.pass.cpp70
-rw-r--r--test/std/utilities/optional/optional.relops/not_equal.pass.cpp74
-rw-r--r--test/std/utilities/optional/optional.specalg/make_optional.pass.cpp51
-rw-r--r--test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp45
-rw-r--r--test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp53
-rw-r--r--test/std/utilities/optional/optional.specalg/swap.pass.cpp352
-rw-r--r--test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp26
-rw-r--r--test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp (renamed from test/std/utilities/utility/forward/forward1.fail.cpp)16
-rw-r--r--test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp29
-rw-r--r--test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp5
-rw-r--r--test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp31
-rw-r--r--test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp31
-rw-r--r--test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp35
-rw-r--r--test/std/utilities/template.bitset/bitset.members/test.pass.cpp31
-rw-r--r--test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp2
-rw-r--r--test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp2
-rw-r--r--test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp2
-rw-r--r--test/std/utilities/time/rep.h10
-rw-r--r--test/std/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp6
-rw-r--r--test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp4
-rw-r--r--test/std/utilities/time/time.point/time.point.comparisons/op_less.pass.cpp4
-rw-r--r--test/std/utilities/time/time.point/time.point.cons/convert.pass.cpp4
-rw-r--r--test/std/utilities/time/time.point/time.point.cons/default.pass.cpp3
-rw-r--r--test/std/utilities/time/time.point/time.point.cons/duration.pass.cpp4
-rw-r--r--test/std/utilities/time/time.point/time.point.nonmember/op_+.pass.cpp4
-rw-r--r--test/std/utilities/time/time.point/time.point.nonmember/op_-duration.pass.cpp17
-rw-r--r--test/std/utilities/time/time.point/time.point.nonmember/op_-time_point.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp5
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp8
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp26
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp34
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp50
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp69
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp2
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp88
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp24
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_pair.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp12
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp18
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp40
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp30
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/dtor.pass.cpp35
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp2
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move_pair.pass.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp3
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp2
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp2
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.pass.cpp4
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp6
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp26
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp2
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp56
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp62
-rw-r--r--test/std/utilities/utility/exchange/exchange.pass.cpp4
-rw-r--r--test/std/utilities/utility/forward/forward.fail.cpp53
-rw-r--r--test/std/utilities/utility/forward/forward.pass.cpp114
-rw-r--r--test/std/utilities/utility/forward/forward5.fail.cpp25
-rw-r--r--test/std/utilities/utility/forward/forward_03.pass.cpp58
-rw-r--r--test/std/utilities/utility/forward/move.fail.cpp (renamed from test/std/utilities/utility/forward/move_only.pass.cpp)21
-rw-r--r--test/std/utilities/utility/forward/move.pass.cpp121
-rw-r--r--test/std/utilities/utility/forward/move_copy.pass.cpp61
-rw-r--r--test/std/utilities/utility/forward/move_only1.fail.cpp52
-rw-r--r--test/std/utilities/utility/forward/move_only2.fail.cpp52
-rw-r--r--test/std/utilities/utility/forward/move_only3.fail.cpp49
-rw-r--r--test/std/utilities/utility/forward/move_only4.fail.cpp52
-rw-r--r--test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp4
-rw-r--r--test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp4
-rw-r--r--test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp2
-rw-r--r--test/std/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp6
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/U_V.pass.cpp74
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_const_pair_U_V.pass.cpp2
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp101
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp49
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp68
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp6
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp140
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp76
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/const_first_const_second_cxx03.pass.cpp42
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp149
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.pass.cpp29
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp4
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp16
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/dtor.pass.cpp32
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp2
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/not_constexpr_cxx11.fail.cpp57
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp139
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/special_member_generation_test.pass.cpp127
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp4
-rw-r--r--test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp6
-rw-r--r--test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp28
-rw-r--r--test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp17
-rw-r--r--test/std/utilities/utility/pairs/pairs.spec/non_member_swap.pass.cpp4
-rw-r--r--test/std/utilities/utility/utility.inplace/inplace.pass.cpp74
-rw-r--r--test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp37
-rw-r--r--test/std/utilities/variant/variant.general/nothing_to_do.pass.cpp (renamed from test/std/utilities/utility/forward/forward6.fail.cpp)15
-rw-r--r--test/std/utilities/variant/variant.get/get_if_index.pass.cpp132
-rw-r--r--test/std/utilities/variant/variant.get/get_if_type.pass.cpp130
-rw-r--r--test/std/utilities/variant/variant.get/get_index.pass.cpp287
-rw-r--r--test/std/utilities/variant/variant.get/get_type.pass.cpp287
-rw-r--r--test/std/utilities/variant/variant.get/holds_alternative.pass.cpp38
-rw-r--r--test/std/utilities/variant/variant.hash/hash.pass.cpp124
-rw-r--r--test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp77
-rw-r--r--test/std/utilities/variant/variant.helpers/variant_size.pass.cpp44
-rw-r--r--test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp55
-rw-r--r--test/std/utilities/variant/variant.monostate/monostate.pass.cpp28
-rw-r--r--test/std/utilities/variant/variant.relops/relops.pass.cpp227
-rw-r--r--test/std/utilities/variant/variant.synopsis/variant_npos.pass.cpp (renamed from test/std/utilities/utility/forward/forward4.fail.cpp)18
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp232
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp397
-rw-r--r--test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp319
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp112
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp159
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp112
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp103
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp103
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp113
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp110
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp197
-rw-r--r--test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp75
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp137
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp85
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp138
-rw-r--r--test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp85
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp58
-rw-r--r--test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp51
-rw-r--r--test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp591
-rw-r--r--test/std/utilities/variant/variant.variant/variant_array.fail.cpp33
-rw-r--r--test/std/utilities/variant/variant.variant/variant_empty.fail.cpp26
-rw-r--r--test/std/utilities/variant/variant.variant/variant_reference.fail.cpp28
-rw-r--r--test/std/utilities/variant/variant.variant/variant_void.fail.cpp33
-rw-r--r--test/std/utilities/variant/variant.visit/visit.pass.cpp291
380 files changed, 19409 insertions, 1207 deletions
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
index a5663a2e063e..0aef2af85ccf 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -23,8 +25,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A1<int> a3(3);
@@ -108,5 +108,4 @@ int main()
std::scoped_allocator_adaptor<A2<int>, A3<int>>(A2<int>(5), A3<int>(6))));
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp
index 9d40cf55a144..8fbbcebe1268 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -23,8 +25,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<double>> B;
typedef std::scoped_allocator_adaptor<A1<int>> A;
@@ -65,5 +65,4 @@ int main()
assert(a2 == a1);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp
index 02e9dff7d7d3..8b585e5f6243 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -23,8 +25,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<double>> B;
typedef std::scoped_allocator_adaptor<A1<int>> A;
@@ -70,6 +70,4 @@ int main()
assert(A3<int>::move_called == true);
assert(a2 == a1);
}
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp
index 21055325112f..86f16891ac3c 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a1(A1<int>(3));
@@ -65,6 +65,4 @@ int main()
assert(A3<int>::move_called == false);
assert(a2 == a1);
}
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp
index 2a1d781eb9cd..b335935e333d 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a;
@@ -54,5 +54,4 @@ int main()
assert(A3<int>::move_called == false);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp
index 727907e3ec76..dd8cf4273272 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a;
@@ -45,5 +45,4 @@ int main()
assert(A1<int>::allocate_called == true);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp
index cae42de66905..f5ce83aa4f6c 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a;
@@ -66,5 +66,4 @@ int main()
assert(a.allocate(10, (const void*)20) == (int*)20);
assert(A2<int>::allocate_called == true);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp
index f94b0e19ac90..dc629edec54a 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -20,8 +22,6 @@
#include "allocators.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
struct B
{
static bool constructed;
@@ -111,11 +111,8 @@ struct F
bool F::constructed = false;
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::scoped_allocator_adaptor<A1<std::string>> A;
@@ -188,6 +185,4 @@ int main()
assert(A3<F>::constructed);
s->~S();
}
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
new file mode 100644
index 000000000000..4e73d8064317
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 0>;
+ using U = UsesAllocatorV2<VoidAlloc, 0>;
+ using Pair = std::pair<T, U>;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&>&&,
+ std::tuple<SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 0>;
+ using U = NotUsesAllocator<VoidAlloc, 0>;
+ using Pair = std::pair<T, U>;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&>&&,
+ std::tuple<>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 0>;
+ using U = UsesAllocatorV2<VoidAlloc2, 0>;
+ using Pair = std::pair<T, U>;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&>&&,
+ std::tuple<SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 0>;
+ using U = NotUsesAllocator<VoidAlloc2, 0>;
+ using Pair = std::pair<T, U>;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr);
+ assert(checkConstruct<>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&>&&,
+ std::tuple<>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp
new file mode 100644
index 000000000000..9effb6eded37
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_const_lvalue_pair.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>const&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ const PairIn in(x, std::move(y));
+ A.construct(ptr, in);
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ const PairIn in(x, y);
+ A.construct(ptr, in);
+ assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int const&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ const PairIn in(x, std::move(y));
+ A.construct(ptr, in);
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int const&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const &>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ const PairIn in(x, y);
+ A.construct(ptr, in);
+ assert(checkConstruct<int const&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int const&>&&,
+ std::tuple<int const&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp
new file mode 100644
index 000000000000..4d371f206e65
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_piecewise.pass.cpp
@@ -0,0 +1,156 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*,
+// piecewise_construct_t, tuple<Args1...>, tuple<Args2...>)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(x),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(std::move(x)),
+ std::forward_as_tuple(y));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(x),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int &&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::piecewise_construct,
+ std::forward_as_tuple(std::move(x)),
+ std::forward_as_tuple(std::move(y)));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp
new file mode 100644
index 000000000000..1d0fb5157c02
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_rvalue.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>&&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ PairIn in(x, std::move(y));
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const&>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ PairIn in(x, y);
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int&, int const&&>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ PairIn in(x, std::move(y));
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int const&&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ using PairIn = std::pair<int, int const &>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ PairIn in(x, y);
+ A.construct(ptr, std::move(in));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp
new file mode 100644
index 000000000000..840f4ecc616d
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair_values.pass.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class U1, class U2, class Tp, class Vp>
+// void scoped_allocator_adaptor::construct(pair<U1, U2>*, Tp&&, Up&&)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+
+void test_no_inner_alloc()
+{
+ using VoidAlloc = CountingAllocator<void>;
+ AllocController P;
+ {
+ using T = UsesAllocatorV1<VoidAlloc, 1>;
+ using U = UsesAllocatorV2<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, x, std::move(y));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&>&&,
+ std::tuple<int const&&, SA&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+
+ }
+ P.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc, 1>;
+ using U = NotUsesAllocator<VoidAlloc, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Alloc = CountingAllocator<Pair>;
+ using SA = std::scoped_allocator_adaptor<Alloc>;
+ static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Alloc CA(P);
+ SA A(CA);
+ A.construct(ptr, std::move(x), y);
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
+ assert(checkConstruct<int const&>(ptr->second, UA_None));
+ assert((P.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SA&, int&&>&&,
+ std::tuple<int const&>&&
+ >(CA, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+
+void test_with_inner_alloc()
+{
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 1>;
+ using U = UsesAllocatorV2<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, x, std::move(y));
+ assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
+ std::tuple<int &&, SAInner&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+ {
+ using T = UsesAllocatorV3<VoidAlloc2, 1>;
+ using U = NotUsesAllocator<VoidAlloc2, 1>;
+ using Pair = std::pair<T, U>;
+ int x = 42;
+ const int y = 101;
+ using Outer = CountingAllocator<Pair, 1>;
+ using Inner = CountingAllocator<Pair, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ A.construct(ptr, std::move(x), std::move(y));
+ assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
+ assert(checkConstruct<int const&&>(ptr->second, UA_None));
+ assert((POuter.checkConstruct<std::piecewise_construct_t const&,
+ std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
+ std::tuple<int const&&>&&
+ >(O, ptr)));
+ A.destroy(ptr);
+ std::free(ptr);
+ }
+}
+int main() {
+ test_no_inner_alloc();
+ test_with_inner_alloc();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp
new file mode 100644
index 000000000000..867cc74082e7
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_type.pass.cpp
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <scoped_allocator>
+
+// template <class OtherAlloc, class ...InnerAlloc>
+// class scoped_allocator_adaptor
+
+// template <class T, class ...Args>
+// void scoped_allocator_adaptor::construct(T*, Args&&...)
+
+#include <scoped_allocator>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "uses_alloc_types.hpp"
+#include "controlled_allocators.hpp"
+
+// — If uses_allocator_v<T, inner_allocator_type> is false and
+// is_constructible_v<T, Args...> is true, calls
+// OUTERMOST_ALLOC_TRAITS(*this)::construct(
+// OUTERMOST (*this), p, std::forward<Args>(args)...).
+void test_bullet_one() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = NotUsesAllocator<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(!std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_None)));
+ assert((POuter.checkConstruct<int&, int const&, int&&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+
+// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
+// is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is
+// true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
+// allocator_arg, inner_allocator(), std::forward<Args>(args)...).
+void test_bullet_two() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV1<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I)));
+ assert((POuter.checkConstruct<std::allocator_arg_t const&,
+ SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
+// is_constructible_v<T, Args..., inner_allocator_type&> is true, calls
+// OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
+// std::forward<Args>(args)..., inner_allocator()).
+void test_bullet_three() {
+ using VoidAlloc1 = CountingAllocator<void, 1>;
+ using VoidAlloc2 = CountingAllocator<void, 2>;
+
+ AllocController POuter;
+ AllocController PInner;
+ {
+ using T = UsesAllocatorV2<VoidAlloc2, 3>;
+ using Outer = CountingAllocator<T, 1>;
+ using Inner = CountingAllocator<T, 2>;
+ using SA = std::scoped_allocator_adaptor<Outer, Inner>;
+ using SAInner = std::scoped_allocator_adaptor<Inner>;
+ static_assert(!std::uses_allocator<T, Outer>::value, "");
+ static_assert(std::uses_allocator<T, Inner>::value, "");
+ T* ptr = (T*)::operator new(sizeof(T));
+ Outer O(POuter);
+ Inner I(PInner);
+ SA A(O, I);
+ int x = 42;
+ int const& cx = x;
+ A.construct(ptr, x, cx, std::move(x));
+ assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I)));
+ assert((POuter.checkConstruct<
+ int&, int const&, int&&,
+ SA::inner_allocator_type&>(O, ptr)));
+ A.destroy(ptr);
+ ::operator delete((void*)ptr);
+ }
+ PInner.reset();
+ POuter.reset();
+}
+
+int main() {
+ test_bullet_one();
+ test_bullet_two();
+ test_bullet_three();
+}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp
index bf77f29f7145..7924140cf2cd 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,7 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
@@ -42,5 +43,4 @@ int main()
assert((A1<int>::deallocate_called == std::pair<int*, std::size_t>((int*)10, 20)));
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp
index 0ff3880f9fc1..96850d783b99 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -32,8 +34,6 @@ bool B::constructed = false;
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<B>> A;
A a;
@@ -66,5 +66,4 @@ int main()
assert(A3<S>::destroy_called);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp
index 0fb55b692cdb..9b892abd81f3 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -22,8 +24,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a(A1<int>(5));
@@ -41,5 +41,4 @@ int main()
std::scoped_allocator_adaptor<A2<int>, A3<int>>(A2<int>(6), A3<int>(8))));
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp
index a5275ee30253..8b88dcc963dd 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
const A a(A1<int>(100));
@@ -39,5 +39,4 @@ int main()
assert(a.max_size() == 200);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp
index 2297612e6098..238d46017b0a 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -22,7 +24,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
@@ -39,6 +40,4 @@ int main()
A a(A1<int>(5), A2<int>(6), A3<int>(8));
assert(a.outer_allocator() == A1<int>(5));
}
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp
index f9f0ffa2ad2a..8ee048bb99f1 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a1(A1<int>(3));
@@ -51,5 +51,4 @@ int main()
assert(a2.inner_allocator().inner_allocator().outer_allocator().id() == -1);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp
index 4303b95166c7..f4c106014a15 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>>::inner_allocator_type,
std::scoped_allocator_adaptor<A1<int>>>::value), "");
@@ -34,6 +34,4 @@ int main()
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::inner_allocator_type,
std::scoped_allocator_adaptor<A2<int>, A3<int>>>::value), "");
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp
index 90fe944125b5..f8a9ea0f9eca 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -22,8 +24,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
// sanity checks
static_assert( (std::is_same<
std::allocator_traits<A1<int>>::is_always_equal, std::false_type>::value
@@ -69,7 +69,4 @@ int main()
std::allocator_traits<A2<int>>::is_always_equal::value &&
std::allocator_traits<A3<int>>::is_always_equal::value)
), "");
-
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp
index ceb941380dc7..4c6aabe2160e 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_copy_assignment,
std::false_type>::value), "");
@@ -35,5 +35,4 @@ int main()
std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_copy_assignment,
std::true_type>::value), "");
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp
index 04da50706536..f6f092ba575a 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_move_assignment,
std::false_type>::value), "");
@@ -35,5 +35,4 @@ int main()
std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_move_assignment,
std::true_type>::value), "");
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp
index 4a66bbd46749..6b7273e266be 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -21,8 +23,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_swap,
std::false_type>::value), "");
@@ -34,6 +34,4 @@ int main()
static_assert((std::is_same<
std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_swap,
std::true_type>::value), "");
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp
index 72f0e867b1d2..2cf548550e1f 100644
--- a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/copy_assign.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -22,7 +24,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a1(A1<int>(3));
@@ -68,5 +69,4 @@ int main()
assert(A3<int>::move_called == false);
assert(aN == a1);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp
index 51dd67f9ffdc..4f7a3af12544 100644
--- a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -29,8 +31,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a1(A1<int>(3));
@@ -59,6 +59,4 @@ int main()
assert(a2 != a1);
assert(!(a2 == a1));
}
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp
index 0dc479c246c9..68f5a7ea2879 100644
--- a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/move_assign.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -22,7 +24,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::scoped_allocator_adaptor<A1<int>> A;
A a1(A1<int>(3));
@@ -68,5 +69,4 @@ int main()
assert(A3<int>::move_called == true);
assert(aN == a1);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/allocator.adaptor/types.pass.cpp b/test/std/utilities/allocator.adaptor/types.pass.cpp
index 7beff48bbf46..fcc99b191108 100644
--- a/test/std/utilities/allocator.adaptor/types.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/types.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// template <class OuterAlloc, class... InnerAllocs>
@@ -30,8 +32,6 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
static_assert((std::is_base_of<
A1<int>,
std::scoped_allocator_adaptor<A1<int>>
@@ -97,6 +97,4 @@ int main()
static_assert((std::is_same<
std::scoped_allocator_adaptor<A2<int>, A1<int>>::const_void_pointer,
const void*>::value), "");
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
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
new file mode 100644
index 000000000000..eba9bc6d5feb
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
@@ -0,0 +1,197 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any& operator=(any const &);
+
+// Test copy assignment
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_copy_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_copy_assign_empty() {
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs;
+ any const rhs(LHS(42));
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 1);
+ assert(LHS::count == 2);
+
+ assertContains<LHS>(lhs, 42);
+ assertContains<LHS>(rhs, 42);
+ }
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs;
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 0);
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(lhs);
+ assertEmpty(rhs);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_copy_assign_self() {
+ // empty
+ {
+ any a;
+ a = a;
+ assertEmpty(a);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // small
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+
+ a = a;
+
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(small::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // large
+ {
+ any a(large(1));
+ assert(large::count == 1);
+
+ a = a;
+
+ assert(large::count == 1);
+ assertContains<large>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ }
+ assert(large::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
+
+template <class Tp>
+void test_copy_assign_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw =
+ [](any& lhs, any const& rhs) {
+ try {
+ lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ any const rhs((Tp(1)));
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ assertContains<Tp>(rhs, 1);
+ }
+ {
+ any lhs((small(2)));
+ any const rhs((Tp(1)));
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ assertContains<Tp>(rhs, 1);
+ }
+ {
+ any lhs((large(2)));
+ any const rhs((Tp(1)));
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ assertContains<Tp>(rhs, 1);
+ }
+#endif
+}
+
+int main() {
+ test_copy_assign<small1, small2>();
+ test_copy_assign<large1, large2>();
+ test_copy_assign<small, large>();
+ test_copy_assign<large, small>();
+ test_copy_assign_empty<small>();
+ test_copy_assign_empty<large>();
+ test_copy_assign_self();
+ test_copy_assign_throws<small_throws_on_copy>();
+ test_copy_assign_throws<large_throws_on_copy>();
+}
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
new file mode 100644
index 000000000000..2063e4f1e9f1
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.assign/move.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any& operator=(any &&);
+
+// Test move assignment.
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_move_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ LHS const s1(1);
+ any a(s1);
+ RHS const s2(2);
+ any a2(s2);
+
+ assert(LHS::count == 2);
+ assert(RHS::count == 2);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 2 + a2.has_value());
+ LIBCPP_ASSERT(RHS::count == 2); // libc++ leaves the object empty
+
+ assertContains<RHS>(a, 2);
+ if (a2.has_value())
+ assertContains<RHS>(a2, 0);
+ LIBCPP_ASSERT(!a2.has_value());
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_move_assign_empty() {
+ assert(LHS::count == 0);
+ {
+ any a;
+ any a2((LHS(1)));
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1 + a2.has_value());
+ LIBCPP_ASSERT(LHS::count == 1);
+
+ assertContains<LHS>(a, 1);
+ if (a2.has_value())
+ assertContains<LHS>(a2, 0);
+ LIBCPP_ASSERT(!a2.has_value());
+ }
+ assert(LHS::count == 0);
+ {
+ any a((LHS(1)));
+ any a2;
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(a);
+ assertEmpty(a2);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_move_assign_noexcept() {
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1 = std::move(a2))
+ , "any & operator=(any &&) must be noexcept"
+ );
+}
+
+int main() {
+ test_move_assign_noexcept();
+ test_move_assign<small1, small2>();
+ test_move_assign<large1, large2>();
+ test_move_assign<small, large>();
+ test_move_assign<large, small>();
+ test_move_assign_empty<small>();
+ test_move_assign_empty<large>();
+}
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
new file mode 100644
index 000000000000..6af481714922
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.assign/value.pass.cpp
@@ -0,0 +1,209 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class ValueType>
+// any& operator=(ValueType&&);
+
+// Test value copy and move assignment.
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_assign_value() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 1);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::moved >= 1);
+ assert(RHS::copied == 0);
+ assert(LHS::count == 0);
+ assert(RHS::count == 1 + rhs.has_value());
+ LIBCPP_ASSERT(!rhs.has_value());
+
+ assertContains<RHS>(lhs, 2);
+ if (rhs.has_value())
+ assertContains<RHS>(rhs, 0);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class RHS>
+void test_assign_value_empty() {
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 1);
+ assert(RHS::moved >= 0);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 0);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 0);
+ assert(RHS::moved >= 1);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+}
+
+
+template <class Tp, bool Move = false>
+void test_assign_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw =
+ [](any& lhs, auto&& rhs) {
+ try {
+ Move ? lhs = std::move(rhs)
+ : lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ Tp rhs(1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ }
+ {
+ any lhs((small(2)));
+ Tp rhs(1);
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ }
+ {
+ any lhs((large(2)));
+ Tp rhs(1);
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ }
+#endif
+}
+
+
+// Test that any& operator=(ValueType&&) is *never* selected for:
+// * std::in_place type.
+// * Non-copyable types
+void test_sfinae_constraints() {
+ { // Only the constructors are required to SFINAE on in_place_t
+ using Tag = std::in_place_type_t<int>;
+ using RawTag = std::remove_reference_t<Tag>;
+ static_assert(std::is_assignable<std::any, RawTag&&>::value, "");
+ }
+ {
+ struct Dummy { Dummy() = delete; };
+ using T = std::in_place_type_t<Dummy>;
+ static_assert(std::is_assignable<std::any, T>::value, "");
+ }
+ {
+ // Test that the ValueType&& constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(NoCopy&&) = default;
+ };
+ static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
+ static_assert(!std::is_assignable<std::any, NoCopy&>::value, "");
+ }
+}
+
+int main() {
+ test_assign_value<small1, small2>();
+ test_assign_value<large1, large2>();
+ test_assign_value<small, large>();
+ test_assign_value<large, small>();
+ test_assign_value_empty<small>();
+ test_assign_value_empty<large>();
+ test_assign_throws<small_throws_on_copy>();
+ test_assign_throws<large_throws_on_copy>();
+ test_assign_throws<throws_on_move, /* Move = */ true>();
+ test_sfinae_constraints();
+}
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
new file mode 100644
index 000000000000..021c9e452841
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any(any const &);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class Type>
+void test_copy_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ any const a((Type(42)));
+ assert(Type::count == 1);
+ try {
+ any const a2(a);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_copy_empty() {
+ DisableAllocationGuard g; ((void)g); // No allocations should occur.
+ any a1;
+ any a2(a1);
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_copy()
+{
+ // Copying small types should not perform any allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+
+ any a2(a);
+
+ assert(Type::copied == 1);
+ assert(Type::count == 2);
+ assertContains<Type>(a, 42);
+ assertContains<Type>(a2, 42);
+
+ // Modify a and check that a2 is unchanged
+ modifyValue<Type>(a, -1);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 42);
+
+ // modify a2 and check that a is unchanged
+ modifyValue<Type>(a2, 999);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 999);
+
+ // clear a and check that a2 is unchanged
+ a.reset();
+ assertEmpty(a);
+ assertContains<Type>(a2, 999);
+ }
+ assert(Type::count == 0);
+}
+
+int main() {
+ test_copy<small>();
+ test_copy<large>();
+ test_copy_empty();
+ test_copy_throws<small_throws_on_copy>();
+ test_copy_throws<large_throws_on_copy>();
+}
diff --git a/test/std/utilities/any/any.class/any.cons/default.pass.cpp b/test/std/utilities/any/any.class/any.cons/default.pass.cpp
new file mode 100644
index 000000000000..ed7a948e00a2
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.cons/default.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any() noexcept;
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "any_helpers.h"
+#include "count_new.hpp"
+
+int main()
+{
+ using std::any;
+ {
+ static_assert(
+ std::is_nothrow_default_constructible<any>::value
+ , "Must be default constructible"
+ );
+ }
+ {
+ struct TestConstexpr : public std::any {
+ constexpr TestConstexpr() : std::any() {}
+ };
+#ifdef _LIBCPP_SAFE_STATIC
+ _LIBCPP_SAFE_STATIC static std::any a;
+ ((void)a);
+#endif
+ }
+ {
+ DisableAllocationGuard g; ((void)g);
+ any const a;
+ assertEmpty(a);
+ }
+}
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
new file mode 100644
index 000000000000..4cf5d914f31d
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
@@ -0,0 +1,194 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class T, class ...Args> any(in_place_type_t<T>, Args&&...);
+// template <class T, class U, class ...Args>
+// any(in_place_type_t<T>, initializer_list<U>, Args&&...);
+
+// Test construction from a value.
+// Concerns:
+// ---------
+// 1. The value is properly move/copied depending on the value category.
+// 2. Both small and large values are properly handled.
+
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+#include "test_convertible.hpp"
+
+using std::any;
+using std::any_cast;
+
+template <class Type>
+void test_in_place_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Type>);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 0);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ { // Test that the in_place argument is properly decayed
+ any a(std::in_place_type<Type&>);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 0);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Type>, 101);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Type>, -1, 42, -1);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_in_place_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a(std::in_place_type<Type>);
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a(std::in_place_type<Type>, -1, 42, -1);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a(std::in_place_type<Type>, {-1, 42, -1});
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a(std::in_place_type<Type&>, {-1, 42, -1}, x);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+void test_func() {}
+
+void test_in_place_type_decayed() {
+ {
+ using Type = decltype(test_func);
+ using DecayT = void(*)();
+ any a(std::in_place_type<Type>, test_func);
+ assert(containsType<DecayT>(a));
+ assert(any_cast<DecayT>(a) == test_func);
+ }
+ {
+ int my_arr[5];
+ using Type = int(&)[5];
+ using DecayT = int*;
+ any a(std::in_place_type<Type>, my_arr);
+ assert(containsType<DecayT>(a));
+ assert(any_cast<DecayT>(a) == my_arr);
+ }
+ {
+ using Type = int[5];
+ using DecayT = int*;
+ any a(std::in_place_type<Type>);
+ assert(containsType<DecayT>(a));
+ assert(any_cast<DecayT>(a) == nullptr);
+ }
+}
+
+void test_ctor_sfinae() {
+ {
+ // Test that the init-list ctor SFINAE's away properly when
+ // construction would be ill-formed.
+ using IL = std::initializer_list<int>;
+ static_assert(!std::is_constructible<std::any,
+ std::in_place_type_t<int>, IL>::value, "");
+ static_assert(std::is_constructible<std::any,
+ std::in_place_type_t<small_tracked_t>, IL>::value, "");
+ }
+ {
+ // Test that the tagged dispatch constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ NoCopy(std::initializer_list<int>, int) {}
+ };
+ using Tag = std::in_place_type_t<NoCopy>;
+ using RefTag = std::in_place_type_t<NoCopy&>;
+ using IL = std::initializer_list<int>;
+ static_assert(!std::is_constructible<std::any, Tag>::value, "");
+ static_assert(!std::is_constructible<std::any, Tag, int>::value, "");
+ static_assert(!std::is_constructible<std::any, Tag, IL, int>::value, "");
+ static_assert(!std::is_constructible<std::any, RefTag>::value, "");
+ static_assert(!std::is_constructible<std::any, RefTag, int>::value, "");
+ static_assert(!std::is_constructible<std::any, RefTag, IL, int>::value, "");
+ }
+}
+
+struct Implicit {
+ Implicit(int) {}
+ Implicit(int, int, int) {}
+ Implicit(std::initializer_list<int>, int) {}
+};
+
+void test_constructor_explicit() {
+ using I = Implicit;
+ using IT = std::in_place_type_t<I>;
+ static_assert(!test_convertible<std::any, IT, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, int>::value, "");
+ static_assert(!test_convertible<std::any, IT, int, int, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, int, int, int>::value, "");
+ static_assert(!test_convertible<std::any, IT, std::initializer_list<int>&, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, std::initializer_list<int>&, int>::value, "");
+}
+
+int main() {
+ test_in_place_type<small>();
+ test_in_place_type<large>();
+ test_in_place_type<small_throws_on_copy>();
+ test_in_place_type<large_throws_on_copy>();
+ test_in_place_type<throws_on_move>();
+ test_in_place_type_tracked<small_tracked_t>();
+ test_in_place_type_tracked<large_tracked_t>();
+ test_in_place_type_decayed();
+ test_ctor_sfinae();
+ test_constructor_explicit();
+}
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
new file mode 100644
index 000000000000..fb7dda886fe7
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.cons/move.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any(any &&) noexcept;
+
+#include <any>
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+// Moves are always noexcept. The throws_on_move object
+// must be stored dynamically so the pointer is moved and
+// not the stored object.
+void test_move_does_not_throw()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v(42);
+ any a(v);
+ assert(throws_on_move::count == 2);
+ // No allocations should be performed after this point.
+ DisableAllocationGuard g; ((void)g);
+ try {
+ any const a2(std::move(a));
+ assertEmpty(a);
+ assertContains<throws_on_move>(a2, 42);
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ assertEmpty(a);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+void test_move_empty() {
+ DisableAllocationGuard g; ((void)g); // no allocations should be performed.
+
+ any a1;
+ any a2(std::move(a1));
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_move() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Moving should not perform allocations since it must be noexcept.
+ DisableAllocationGuard g; ((void)g);
+
+ any a2(std::move(a));
+
+ assert(Type::moved == 1 || Type::moved == 2); // zero or more move operations can be performed.
+ assert(Type::copied == 0); // no copies can be performed.
+ assert(Type::count == 1 + a.has_value());
+ assertContains<Type>(a2, 42);
+ LIBCPP_ASSERT(!a.has_value()); // Moves are always destructive.
+ if (a.has_value())
+ assertContains<Type>(a, 0);
+ }
+ assert(Type::count == 0);
+}
+
+int main()
+{
+ // noexcept test
+ {
+ static_assert(
+ std::is_nothrow_move_constructible<any>::value
+ , "any must be nothrow move constructible"
+ );
+ }
+ test_move<small>();
+ test_move<large>();
+ test_move_empty();
+ test_move_does_not_throw();
+}
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
new file mode 100644
index 000000000000..a164fbeb52fe
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.cons/value.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class Value> any(Value &&)
+
+// Test construction from a value.
+// Concerns:
+// ---------
+// 1. The value is properly move/copied depending on the value category.
+// 2. Both small and large values are properly handled.
+
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class Type>
+void test_copy_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ Type const t(42);
+ assert(Type::count == 1);
+ try {
+ any const a2(t);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_move_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v;
+ assert(throws_on_move::count == 1);
+ try {
+ any const a(std::move(v));
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+template <class Type>
+void test_copy_move_value() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(t);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(std::move(t));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ assertContains<Type>(a, 42);
+ }
+}
+
+// Test that any(ValueType&&) is *never* selected for a std::in_place_type_t specialization.
+void test_sfinae_constraints() {
+ using BadTag = std::in_place_type_t<int>;
+ using OKTag = std::in_place_t;
+ // Test that the tag type is properly handled in SFINAE
+ BadTag t = std::in_place_type<int>;
+ OKTag ot = std::in_place;
+ {
+ std::any a(t);
+ assertContains<int>(a, 0);
+ }
+ {
+ std::any a(std::move(t));
+ assertContains<int>(a, 0);
+ }
+ {
+ std::any a(ot);
+ assert(containsType<OKTag>(a));
+ }
+ {
+ struct Dummy { Dummy() = delete; };
+ using T = std::in_place_type_t<Dummy>;
+ static_assert(!std::is_constructible<std::any, T>::value, "");
+ }
+ {
+ // Test that the ValueType&& constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ };
+ static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
+ static_assert(!std::is_constructible<std::any, NoCopy&>::value, "");
+ static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
+ }
+}
+
+int main() {
+ test_copy_move_value<small>();
+ test_copy_move_value<large>();
+ test_copy_value_throws<small_throws_on_copy>();
+ test_copy_value_throws<large_throws_on_copy>();
+ test_move_value_throws();
+ test_sfinae_constraints();
+} \ No newline at end of file
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
new file mode 100644
index 000000000000..65d94fd1e0a4
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -0,0 +1,262 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class T, class ...Args> emplace(Args&&...);
+// template <class T, class U, class ...Args>
+// void emplace(initializer_list<U>, Args&&...);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+struct Tracked {
+ static int count;
+ Tracked() {++count;}
+ ~Tracked() { --count; }
+};
+int Tracked::count = 0;
+
+template <class Type>
+void test_emplace_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>();
+
+ assert(Tracked::count == 0);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 0);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>(101);
+
+ assert(Tracked::count == 0);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>(-1, 42, -1);
+
+ assert(Tracked::count == 0);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_emplace_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>();
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>(-1, 42, -1);
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>({-1, 42, -1});
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a(std::in_place_type<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>({-1, 42, -1}, x);
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+struct SmallThrows {
+ SmallThrows(int) { throw 42; }
+ SmallThrows(std::initializer_list<int>, int) { throw 42; }
+};
+static_assert(IsSmallObject<SmallThrows>::value, "");
+
+struct LargeThrows {
+ LargeThrows(int) { throw 42; }
+ LargeThrows(std::initializer_list<int>, int) { throw 42; }
+ int data[sizeof(std::any)];
+};
+static_assert(!IsSmallObject<LargeThrows>::value, "");
+
+template <class Type>
+void test_emplace_throws()
+{
+ // any stores small type
+ {
+ std::any a(small{42});
+ assert(small::count == 1);
+ try {
+ a.emplace<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(small::count == 0);
+ }
+ {
+ std::any a(small{42});
+ assert(small::count == 1);
+ try {
+ a.emplace<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(small::count == 0);
+ }
+ // any stores large type
+ {
+ std::any a(large{42});
+ assert(large::count == 1);
+ try {
+ a.emplace<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(large::count == 0);
+ }
+ {
+ std::any a(large{42});
+ assert(large::count == 1);
+ try {
+ a.emplace<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(large::count == 0);
+ }
+}
+
+#endif
+
+template <class T, class ...Args>
+constexpr auto has_emplace(int)
+ -> decltype(std::any{}.emplace<T>(std::declval<Args>()...), true) { return true; }
+
+template <class ...Args>
+constexpr bool has_emplace(long) { return false; }
+
+template <class ...Args>
+constexpr bool has_emplace() { return has_emplace<Args...>(0); }
+
+
+template <class T, class IT, class ...Args>
+constexpr auto has_emplace_init_list(int)
+ -> decltype(std::any{}.emplace<T>(
+ {std::declval<IT>(), std::declval<IT>(), std::declval<IT>()},
+ std::declval<Args>()...), true) { return true; }
+
+template <class ...Args>
+constexpr bool has_emplace_init_list(long) { return false; }
+
+template <class ...Args>
+constexpr bool has_emplace_init_list() { return has_emplace_init_list<Args...>(0); }
+
+
+void test_emplace_sfinae_constraints() {
+ {
+ static_assert(has_emplace<int>(), "");
+ static_assert(has_emplace<int, int>(), "");
+ static_assert(!has_emplace<int, int, int>(), "not constructible");
+ static_assert(!has_emplace_init_list<int, int>(), "not constructible from il");
+ }
+ {
+ static_assert(has_emplace<small>(), "");
+ static_assert(has_emplace<large>(), "");
+ static_assert(!has_emplace<small, void*>(), "");
+ static_assert(!has_emplace<large, void*>(), "");
+
+ static_assert(has_emplace_init_list<small, int>(), "");
+ static_assert(has_emplace_init_list<large, int>(), "");
+ static_assert(!has_emplace_init_list<small, void*>(), "");
+ static_assert(!has_emplace_init_list<large, void*>(), "");
+ }
+ {
+ // Test that the emplace SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ NoCopy(std::initializer_list<int>, int, int) {}
+ };
+ static_assert(!has_emplace<NoCopy>(), "");
+ static_assert(!has_emplace<NoCopy, int>(), "");
+ static_assert(!has_emplace_init_list<NoCopy, int, int, int>(), "");
+ static_assert(!has_emplace<NoCopy&>(), "");
+ static_assert(!has_emplace<NoCopy&, int>(), "");
+ static_assert(!has_emplace_init_list<NoCopy&, int, int, int>(), "");
+ static_assert(!has_emplace<NoCopy&&>(), "");
+ static_assert(!has_emplace<NoCopy&&, int>(), "");
+ static_assert(!has_emplace_init_list<NoCopy&&, int, int, int>(), "");
+
+ }
+}
+
+int main() {
+ test_emplace_type<small>();
+ test_emplace_type<large>();
+ test_emplace_type<small_throws_on_copy>();
+ test_emplace_type<large_throws_on_copy>();
+ test_emplace_type<throws_on_move>();
+ test_emplace_type_tracked<small_tracked_t>();
+ test_emplace_type_tracked<large_tracked_t>();
+ test_emplace_sfinae_constraints();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ test_emplace_throws<SmallThrows>();
+ test_emplace_throws<LargeThrows>();
+#endif
+}
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
new file mode 100644
index 000000000000..45bc70f7a795
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.modifiers/reset.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
+
+// <any>
+
+// any::reset() noexcept
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ using std::any_cast;
+ // empty
+ {
+ any a;
+
+ // noexcept check
+ static_assert(
+ noexcept(a.reset())
+ , "any.reset() must be noexcept"
+ );
+
+ assertEmpty(a);
+
+ a.reset();
+
+ assertEmpty(a);
+ }
+ // small object
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+
+ a.reset();
+
+ assertEmpty<small>(a);
+ assert(small::count == 0);
+ }
+ // large object
+ {
+ any a(large(1));
+ assert(large::count == 1);
+ assertContains<large>(a, 1);
+
+ a.reset();
+
+ assertEmpty<large>(a);
+ assert(large::count == 0);
+ }
+}
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
new file mode 100644
index 000000000000..6fc100943d0f
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// any::swap(any &) noexcept
+
+// Test swap(large, small) and swap(small, large)
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_swap() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ any a1((LHS(1)));
+ any a2(RHS{2});
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ a1.swap(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ assertContains<RHS>(a1, 2);
+ assertContains<LHS>(a2, 1);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ assert(LHS::copied == 0);
+ assert(RHS::copied == 0);
+}
+
+template <class Tp>
+void test_swap_empty() {
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a1.swap(a2);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a2.swap(a1);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ assert(Tp::copied == 0);
+}
+
+void test_noexcept()
+{
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1.swap(a2))
+ , "any::swap(any&) must be noexcept"
+ );
+}
+
+void test_self_swap() {
+ {
+ // empty
+ any a;
+ a.swap(a);
+ assertEmpty(a);
+ }
+ { // small
+ using T = small;
+ any a{T{42}};
+ T::reset();
+ a.swap(a);
+ assertContains<T>(a, 42);
+ assert(T::count == 1);
+ assert(T::copied == 0);
+ LIBCPP_ASSERT(T::moved == 0);
+ }
+ assert(small::count == 0);
+ { // large
+ using T = large;
+ any a{T{42}};
+ T::reset();
+ a.swap(a);
+ assertContains<T>(a, 42);
+ assert(T::count == 1);
+ assert(T::copied == 0);
+ LIBCPP_ASSERT(T::moved == 0);
+ }
+ assert(large::count == 0);
+}
+
+int main()
+{
+ test_noexcept();
+ test_swap_empty<small>();
+ test_swap_empty<large>();
+ test_swap<small1, small2>();
+ test_swap<large1, large2>();
+ test_swap<small, large>();
+ test_swap<large, small>();
+ test_self_swap();
+}
diff --git a/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp b/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp
new file mode 100644
index 000000000000..072ac06776c1
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.observers/has_value.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
+
+// <any>
+
+// any::has_value() noexcept
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ // noexcept test
+ {
+ any a;
+ static_assert(noexcept(a.has_value()), "any::has_value() must be noexcept");
+ }
+ // empty
+ {
+ any a;
+ assert(!a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = 42;
+ assert(a.has_value());
+ }
+ // small object
+ {
+ small const s(1);
+ any a(s);
+ assert(a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = s;
+ assert(a.has_value());
+ }
+ // large object
+ {
+ large const l(1);
+ any a(l);
+ assert(a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = l;
+ assert(a.has_value());
+ }
+}
diff --git a/test/std/utilities/any/any.class/any.observers/type.pass.cpp b/test/std/utilities/any/any.class/any.observers/type.pass.cpp
new file mode 100644
index 000000000000..984c4137db09
--- /dev/null
+++ b/test/std/utilities/any/any.class/any.observers/type.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
+
+// XFAIL: libcpp-no-rtti
+
+// <any>
+
+// any::type() noexcept
+
+#include <any>
+#include <cassert>
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ {
+ any const a;
+ assert(a.type() == typeid(void));
+ static_assert(noexcept(a.type()), "any::type() must be noexcept");
+ }
+ {
+ small const s(1);
+ any const a(s);
+ assert(a.type() == typeid(small));
+
+ }
+ {
+ large const l(1);
+ any const a(l);
+ assert(a.type() == typeid(large));
+ }
+}
diff --git a/test/std/utilities/any/any.class/not_literal_type.pass.cpp b/test/std/utilities/any/any.class/not_literal_type.pass.cpp
new file mode 100644
index 000000000000..91ef5c970a22
--- /dev/null
+++ b/test/std/utilities/any/any.class/not_literal_type.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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// [Note any is a not a literal type --end note]
+
+#include <any>
+#include <type_traits>
+
+int main () {
+ static_assert(!std::is_literal_type<std::any>::value, "");
+}
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
new file mode 100644
index 000000000000..1a5a85482b8f
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class ValueType>
+// ValueType const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::any;
+using std::any_cast;
+
+// Test that the operators are properly noexcept.
+void test_cast_is_noexcept() {
+ any a;
+ static_assert(noexcept(any_cast<int>(&a)), "");
+
+ any const& ca = a;
+ static_assert(noexcept(any_cast<int>(&ca)), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(&a)), int*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&a)), int const*>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(&ca)), int const*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&ca)), int const*>::value, "");
+}
+
+// Test that any_cast handles null pointers.
+void test_cast_nullptr() {
+ any* a = nullptr;
+ assert(nullptr == any_cast<int>(a));
+ assert(nullptr == any_cast<int const>(a));
+
+ any const* ca = nullptr;
+ assert(nullptr == any_cast<int>(ca));
+ assert(nullptr == any_cast<int const>(ca));
+}
+
+// Test casting an empty object.
+void test_cast_empty() {
+ {
+ any a;
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+ // Create as non-empty, then make empty and run test.
+ {
+ any a(42);
+ a.reset();
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+}
+
+template <class Type>
+void test_cast() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ assert(any_cast<int>(&a) == nullptr);
+ assert(any_cast<int const>(&a) == nullptr);
+ assert(any_cast<int const volatile>(&a) == nullptr);
+
+ // Try a cast to the right type, but as a pointer.
+ assert(any_cast<Type*>(&a) == nullptr);
+ assert(any_cast<Type const*>(&a) == nullptr);
+
+ // Check getting a unqualified type from a non-const any.
+ Type* v = any_cast<Type>(&a);
+ assert(v != nullptr);
+ assert(v->value == 42);
+
+ // change the stored value and later check for the new value.
+ v->value = 999;
+
+ // Check getting a const qualified type from a non-const any.
+ Type const* cv = any_cast<Type const>(&a);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a unqualified type from a const any.
+ cv = any_cast<Type>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a const-qualified type from a const any.
+ cv = any_cast<Type const>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check that no more objects were created, copied or moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+void test_cast_non_copyable_type()
+{
+ // Even though 'any' never stores non-copyable types
+ // we still need to support any_cast<NoCopy>(ptr)
+ struct NoCopy { NoCopy(NoCopy const&) = delete; };
+ std::any a(42);
+ std::any const& ca = a;
+ assert(std::any_cast<NoCopy>(&a) == nullptr);
+ assert(std::any_cast<NoCopy>(&ca) == nullptr);
+}
+
+void test_fn() {}
+
+void test_cast_function_pointer() {
+ using T = void(*)();
+ std::any a(test_fn);
+ // An any can never store a function type, but we should at least be able
+ // to ask.
+ assert(std::any_cast<void()>(&a) == nullptr);
+ T fn_ptr = std::any_cast<T>(a);
+ assert(fn_ptr == test_fn);
+}
+
+int main() {
+ test_cast_is_noexcept();
+ test_cast_return_type();
+ test_cast_nullptr();
+ test_cast_empty();
+ test_cast<small>();
+ test_cast<large>();
+ test_cast_non_copyable_type();
+ test_cast_function_pointer();
+}
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
new file mode 100644
index 000000000000..af081ecceefd
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -0,0 +1,313 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class ValueType>
+// ValueType const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+using std::bad_any_cast;
+
+
+// Test that the operators are NOT marked noexcept.
+void test_cast_is_not_noexcept() {
+ any a;
+ static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
+}
+
+template <class Type, class ConstT = Type>
+void checkThrows(any& a)
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ try {
+ any_cast<Type>(a);
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ any_cast<ConstT>(static_cast<any const&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ using RefType = typename std::conditional<
+ std::is_lvalue_reference<Type>::value,
+ typename std::remove_reference<Type>::type&&,
+ Type
+ >::type;
+ any_cast<RefType>(static_cast<any&&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+#else
+ ((void)a);
+#endif
+}
+
+void test_cast_empty() {
+ // None of these operations should allocate.
+ DisableAllocationGuard g; ((void)g);
+ any a;
+ checkThrows<int>(a);
+}
+
+template <class Type>
+void test_cast_to_reference() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ // Check getting a type by reference from a non-const lvalue any.
+ {
+ Type& v = any_cast<Type&>(a);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(a);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const lvalue any.
+ {
+ Type const& v = any_cast<Type const&>(ca);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(ca);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const& v = any_cast<Type const&>(std::move(ca));
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(std::move(ca));
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type&& v = any_cast<Type&&>(std::move(a));
+ assert(v.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+
+ Type&& cv = any_cast<Type&&>(std::move(a));
+ assert(&cv == &v);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const&& v = any_cast<Type const&&>(std::move(a));
+ assert(v.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+
+ Type const&& cv = any_cast<Type const&&>(std::move(a));
+ assert(&cv == &v);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+
+ // Check that no objects have been created/copied/moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+template <class Type>
+void test_cast_to_value() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ Type::reset(); // NOTE: reset does not modify Type::count
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const rvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::moved == 1);
+ assert(Type::copied == 0);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 0);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 0);
+ any_cast<Type&>(a).value = 42; // reset the value
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 0);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 1);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 0);
+ any_cast<Type&>(a).value = 42; // reset the value
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Ensure we still only have 1 Type object alive.
+ assert(Type::count == 1);
+
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+}
+
+int main() {
+ test_cast_is_not_noexcept();
+ test_cast_return_type();
+ test_cast_empty();
+ test_cast_to_reference<small>();
+ test_cast_to_reference<large>();
+ test_cast_to_value<small>();
+ test_cast_to_value<large>();
+}
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
new file mode 100644
index 000000000000..07578a28e82f
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/any_cast_request_invalid_value_category.fail.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+// Try and use the rvalue any_cast to cast to an lvalue reference
+
+#include <any>
+
+struct TestType {};
+using std::any;
+using std::any_cast;
+
+void test_const_lvalue_cast_request_non_const_lvalue()
+{
+ const any a;
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{binding value of type 'const TestType' to reference to type 'TestType' drops 'const' qualifier}}
+ any_cast<TestType &>(a); // expected-note {{requested here}}
+
+ const any a2(42);
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{binding value of type 'const int' to reference to type 'int' drops 'const' qualifier}}
+ any_cast<int&>(a2); // expected-note {{requested here}}
+}
+
+void test_lvalue_any_cast_request_rvalue()
+{
+ any a;
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an lvalue reference or a CopyConstructible type"}}
+ any_cast<TestType &&>(a); // expected-note {{requested here}}
+
+ any a2(42);
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an lvalue reference or a CopyConstructible type"}}
+ any_cast<int&&>(a2); // expected-note {{requested here}}
+}
+
+void test_rvalue_any_cast_request_lvalue()
+{
+ any a;
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}}
+ any_cast<TestType &>(std::move(a)); // expected-note {{requested here}}
+
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}}
+ any_cast<int&>(42);
+}
+
+int main()
+{
+ test_const_lvalue_cast_request_non_const_lvalue();
+ test_lvalue_any_cast_request_rvalue();
+ test_rvalue_any_cast_request_lvalue();
+}
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
new file mode 100644
index 000000000000..3f6955a8cbce
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.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
+
+// <any>
+
+// template <class ValueType>
+// ValueType any_cast(any const &);
+
+// Try and cast away const.
+
+#include <any>
+
+struct TestType {};
+struct TestType2 {};
+
+int main()
+{
+ using std::any;
+ using std::any_cast;
+
+ any a;
+
+ // expected-error@any:* {{binding value of type 'const TestType' to reference to type 'TestType' drops 'const' qualifier}}
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ any_cast<TestType &>(static_cast<any const&>(a)); // expected-note {{requested here}}
+
+ // expected-error@any:* {{cannot cast from lvalue of type 'const TestType' to rvalue reference type 'TestType &&'; types are not compatible}}
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ any_cast<TestType &&>(static_cast<any const&>(a)); // expected-note {{requested here}}
+
+ // expected-error@any:* {{binding value of type 'const TestType2' to reference to type 'TestType2' drops 'const' qualifier}}
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ any_cast<TestType2 &>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+
+ // expected-error@any:* {{cannot cast from lvalue of type 'const TestType2' to rvalue reference type 'TestType2 &&'; types are not compatible}}
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ any_cast<TestType2 &&>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+}
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
new file mode 100644
index 000000000000..ed4b96d644d2
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.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
+
+// <any>
+
+// template <class ValueType>
+// ValueType const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+// Test instantiating the any_cast with a non-copyable type.
+
+#include <any>
+
+using std::any;
+using std::any_cast;
+
+struct no_copy
+{
+ no_copy() {}
+ no_copy(no_copy &&) {}
+ no_copy(no_copy const &) = delete;
+};
+
+struct no_move {
+ no_move() {}
+ no_move(no_move&&) = delete;
+ no_move(no_move const&) {}
+};
+
+int main() {
+ any a;
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an lvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{static_cast from 'no_copy' to 'no_copy' uses deleted function}}
+ any_cast<no_copy>(static_cast<any&>(a)); // expected-note {{requested here}}
+
+ // expected-error@any:* {{static_assert failed "ValueType is required to be a const lvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{static_cast from 'const no_copy' to 'no_copy' uses deleted function}}
+ any_cast<no_copy>(static_cast<any const&>(a)); // expected-note {{requested here}}
+
+ any_cast<no_copy>(static_cast<any &&>(a)); // OK
+
+ // expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
+ // expected-error@any:* {{static_cast from 'typename remove_reference<no_move &>::type' (aka 'no_move') to 'no_move' uses deleted function}}
+ any_cast<no_move>(static_cast<any &&>(a));
+}
diff --git a/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp b/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp
new file mode 100644
index 000000000000..99cc029971a8
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class ValueType>
+// ValueType const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <any>
+
+using std::any;
+using std::any_cast;
+
+int main()
+{
+ any a(1);
+ any_cast<int &>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const&&>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any const& a2 = a;
+ any_cast<int &>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &&>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+}
diff --git a/test/std/utilities/any/any.nonmembers/make_any.pass.cpp b/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
new file mode 100644
index 000000000000..59c06be6aad3
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// template <class T, class ...Args> any make_any(Args&&...);
+// template <class T, class U, class ...Args>
+// any make_any(initializer_list<U>, Args&&...);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+
+template <class Type>
+void test_make_any_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a = std::make_any<Type>();
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 0);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a = std::make_any<Type>(101);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a = std::make_any<Type>(-1, 42, -1);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_make_any_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a = std::make_any<Type>();
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a = std::make_any<Type>(-1, 42, -1);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a = std::make_any<Type>({-1, 42, -1});
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a = std::make_any<Type>({-1, 42, -1}, x);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+struct SmallThrows {
+ SmallThrows(int) { throw 42; }
+ SmallThrows(std::initializer_list<int>, int) { throw 42; }
+};
+static_assert(IsSmallObject<SmallThrows>::value, "");
+
+struct LargeThrows {
+ LargeThrows(int) { throw 42; }
+ LargeThrows(std::initializer_list<int>, int) { throw 42; }
+ int data[sizeof(std::any)];
+};
+static_assert(!IsSmallObject<LargeThrows>::value, "");
+
+template <class Type>
+void test_make_any_throws()
+{
+ {
+ try {
+ std::make_any<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ }
+ {
+ try {
+ std::make_any<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ }
+}
+
+#endif
+
+int main() {
+ test_make_any_type<small>();
+ test_make_any_type<large>();
+ test_make_any_type<small_throws_on_copy>();
+ test_make_any_type<large_throws_on_copy>();
+ test_make_any_type<throws_on_move>();
+ test_make_any_type_tracked<small_tracked_t>();
+ test_make_any_type_tracked<large_tracked_t>();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ test_make_any_throws<SmallThrows>();
+ test_make_any_throws<LargeThrows>();
+
+#endif
+}
diff --git a/test/std/utilities/any/any.nonmembers/swap.pass.cpp b/test/std/utilities/any/any.nonmembers/swap.pass.cpp
new file mode 100644
index 000000000000..1b3785bb1c66
--- /dev/null
+++ b/test/std/utilities/any/any.nonmembers/swap.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <any>
+
+// void swap(any &, any &) noexcept
+
+// swap(...) just wraps any::swap(...). That function is tested elsewhere.
+
+#include <any>
+#include <cassert>
+
+using std::any;
+using std::any_cast;
+
+int main()
+{
+
+ { // test noexcept
+ any a;
+ static_assert(noexcept(swap(a, a)), "swap(any&, any&) must be noexcept");
+ }
+ {
+ any a1(1);
+ any a2(2);
+
+ swap(a1, a2);
+
+ assert(any_cast<int>(a1) == 2);
+ assert(any_cast<int>(a2) == 1);
+ }
+}
diff --git a/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp
index 490dc16b60e2..7419b70e0b8f 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::divides<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<int, F::second_argument_type>::value), "" );
static_assert((std::is_same<int, F::result_type>::value), "" );
assert(f(36, 4) == 9);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::divides<> F2;
const F2 f2 = F2();
assert(f2(36, 4) == 9);
@@ -33,7 +35,7 @@ int main()
constexpr int foo = std::divides<int> () (3, 2);
static_assert ( foo == 1, "" );
- constexpr int bar = std::divides<> () (3.0, 2);
- static_assert ( bar == 1, "" );
+ constexpr double bar = std::divides<> () (3.0, 2);
+ static_assert ( bar == 1.5, "" ); // exact in binary
#endif
}
diff --git a/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp
index 9bda541f896a..25df69d60e96 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::minus<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<int, F::second_argument_type>::value), "" );
static_assert((std::is_same<int, F::result_type>::value), "" );
assert(f(3, 2) == 1);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::minus<> F2;
const F2 f2 = F2();
assert(f2(3,2) == 1);
@@ -33,7 +35,7 @@ int main()
constexpr int foo = std::minus<int> () (3, 2);
static_assert ( foo == 1, "" );
- constexpr int bar = std::minus<> () (3.0, 2);
- static_assert ( bar == 1, "" );
+ constexpr double bar = std::minus<> () (3.0, 2);
+ static_assert ( bar == 1.0, "" );
#endif
}
diff --git a/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
index ca5bba6d5b8e..6f39792e925f 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::modulus<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<int, F::second_argument_type>::value), "" );
static_assert((std::is_same<int, F::result_type>::value), "" );
assert(f(36, 8) == 4);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::modulus<> F2;
const F2 f2 = F2();
assert(f2(36, 8) == 4);
diff --git a/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
index f132c8d4bd9b..2b354826960e 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::multiplies<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<int, F::second_argument_type>::value), "" );
static_assert((std::is_same<int, F::result_type>::value), "" );
assert(f(3, 2) == 6);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::multiplies<> F2;
const F2 f2 = F2();
assert(f2(3,2) == 6);
@@ -33,7 +35,7 @@ int main()
constexpr int foo = std::multiplies<int> () (3, 2);
static_assert ( foo == 6, "" );
- constexpr int bar = std::multiplies<> () (3.0, 2);
- static_assert ( bar == 6, "" );
+ constexpr double bar = std::multiplies<> () (3.0, 2);
+ static_assert ( bar == 6.0, "" );
#endif
}
diff --git a/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp
index 0adac659123b..198894023cd7 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::negate<int> F;
@@ -22,7 +24,7 @@ int main()
static_assert((std::is_same<F::argument_type, int>::value), "" );
static_assert((std::is_same<F::result_type, int>::value), "" );
assert(f(36) == -36);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::negate<> F2;
const F2 f2 = F2();
assert(f2(36) == -36);
@@ -32,7 +34,7 @@ int main()
constexpr int foo = std::negate<int> () (3);
static_assert ( foo == -3, "" );
- constexpr int bar = std::negate<> () (3.0);
- static_assert ( bar == -3, "" );
+ constexpr double bar = std::negate<> () (3.0);
+ static_assert ( bar == -3.0, "" );
#endif
}
diff --git a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp
index ce544c78b676..b56d3ef2b346 100644
--- a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp
+++ b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::plus<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<int, F::second_argument_type>::value), "" );
static_assert((std::is_same<int, F::result_type>::value), "" );
assert(f(3, 2) == 5);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::plus<> F2;
const F2 f2 = F2();
assert(f2(3,2) == 5);
@@ -33,7 +35,7 @@ int main()
constexpr int foo = std::plus<int> () (3, 2);
static_assert ( foo == 5, "" );
- constexpr int bar = std::plus<> () (3.0, 2);
- static_assert ( bar == 5, "" );
+ constexpr double bar = std::plus<> () (3.0, 2);
+ static_assert ( bar == 5.0, "" );
#endif
}
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp
index 63d3c9b0de92..a543fffedbb5 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp
@@ -24,6 +24,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int dummy = 42;
int return_value(int) { return dummy; }
@@ -81,10 +83,10 @@ void do_test(Fn* func) {
// Check that the call operator SFINAE's away when too few arguments
// are provided but is well-formed otherwise.
{
- static_assert(!CheckCall<Bind>(), "");
+ LIBCPP_STATIC_ASSERT(!CheckCall<Bind>(), "");
static_assert(CheckCall<Bind, int>(), "");
static_assert(CheckCall<Bind, int, int>(), "");
- static_assert(!CheckCall<BindR>(), "");
+ LIBCPP_STATIC_ASSERT(!CheckCall<BindR>(), "");
static_assert(CheckCall<BindR, int>(), "");
static_assert(CheckCall<BindR, int, int>(), "");
}
@@ -108,7 +110,7 @@ void do_test_r(Fn* func) {
// Check that the call operator SFINAE's away when too few arguments
// are provided but is well-formed otherwise.
{
- static_assert(!CheckCall<Bind>(), "");
+ LIBCPP_STATIC_ASSERT(!CheckCall<Bind>(), "");
static_assert(CheckCall<Bind, int>(), "");
static_assert(CheckCall<Bind, int, int>(), "");
}
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
index a0c686de77ba..180433109f26 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
@@ -29,7 +29,7 @@ struct DummyUnaryFunction
struct BadUnaryFunction
{
template <typename S>
- constexpr int operator()(S const & s) const
+ constexpr int operator()(S const &) const
{
// Trigger a compile error if this function is instantiated.
// The constexpr is needed so that it is instantiated while checking
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 f61d93aefd89..0d4244b4d860 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
@@ -28,7 +28,7 @@ struct power
T
operator()(T a, T b)
{
- return std::pow(a, b);
+ return static_cast<T>(std::pow(a, b));
}
};
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
index 83fa452fecb3..5d833e28830b 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
@@ -14,12 +14,16 @@
// template<class T> struct is_bind_expression
#include <functional>
+#include "test_macros.h"
template <bool Expected, class T>
void
test(const T&)
{
static_assert(std::is_bind_expression<T>::value == Expected, "");
+#if TEST_STD_VER > 14
+ static_assert(std::is_bind_expression_v<T> == Expected, "");
+#endif
}
struct C {};
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp
index 6a52bd1848e9..1d7c649dfc0e 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp
@@ -12,12 +12,16 @@
// struct is_placeholder
#include <functional>
+#include "test_macros.h"
template <int Expected, class T>
void
test(const T&)
{
static_assert(std::is_placeholder<T>::value == Expected, "");
+#if TEST_STD_VER > 14
+ static_assert(std::is_placeholder_v<T> == Expected, "");
+#endif
}
struct C {};
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp
index 68986ac1aeb3..59709d0ed5b2 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp
@@ -56,8 +56,34 @@ constexpr decltype(std::placeholders::_9) cp9 = std::placeholders::_9;
constexpr decltype(std::placeholders::_10) cp10 = std::placeholders::_10;
#endif // TEST_STD_VER >= 11
+void use_placeholders_to_prevent_unused_warning() {
+#if TEST_STD_VER >= 11
+ ((void)cp1);
+ ((void)cp2);
+ ((void)cp3);
+ ((void)cp4);
+ ((void)cp5);
+ ((void)cp6);
+ ((void)cp7);
+ ((void)cp8);
+ ((void)cp9);
+ ((void)cp10);
+ ((void)default1);
+ ((void)default2);
+ ((void)default3);
+ ((void)default4);
+ ((void)default5);
+ ((void)default6);
+ ((void)default7);
+ ((void)default8);
+ ((void)default9);
+ ((void)default10);
+#endif
+}
+
int main()
{
+ use_placeholders_to_prevent_unused_warning();
test(std::placeholders::_1);
test(std::placeholders::_2);
test(std::placeholders::_3);
diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
index c0135fad1982..12d968f42c0a 100644
--- a/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
+++ b/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::bit_and<int> F;
@@ -27,7 +29,7 @@ int main()
assert(f(0x58D3, 0xEA95) == 0x4891);
assert(f(0x58D3, 0) == 0);
assert(f(0xFFFF, 0x58D3) == 0x58D3);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::bit_and<> F2;
const F2 f2 = F2();
assert(f2(0xEA95, 0xEA95) == 0xEA95);
diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
index cb33df3d84b7..90dd9bc098bb 100644
--- a/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
+++ b/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::bit_or<int> F;
@@ -27,7 +29,7 @@ int main()
assert(f(0x58D3, 0xEA95) == 0xFAD7);
assert(f(0x58D3, 0) == 0x58D3);
assert(f(0xFFFF, 0x58D3) == 0xFFFF);
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::bit_or<> F2;
const F2 f2 = F2();
assert(f2(0xEA95, 0xEA95) == 0xEA95);
diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
index bbf2ce5baf1b..a5cbd17a0d0e 100644
--- a/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
+++ b/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
@@ -29,7 +31,7 @@ int main()
assert(f(0x58D3, 0) == 0x58D3);
assert(f(0xFFFF, 0x58D3) == 0xA72C);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef std::bit_xor<> F2;
const F2 f = F2();
diff --git a/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp
index 66d783a6e357..b23d4e8bb478 100644
--- a/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp
+++ b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp
@@ -19,13 +19,13 @@ void do_pointer_comparison_test() {
#endif
std::vector<std::shared_ptr<T> > pointers;
const std::size_t test_size = 100;
- for (int i=0; i < test_size; ++i)
+ for (size_t i=0; i < test_size; ++i)
pointers.push_back(std::shared_ptr<T>(new T()));
Compare comp;
UIntCompare ucomp;
VoidCompare vcomp;
- for (int i=0; i < test_size; ++i) {
- for (int j=0; j < test_size; ++j) {
+ for (size_t i=0; i < test_size; ++i) {
+ for (size_t j=0; j < test_size; ++j) {
T* lhs = pointers[i].get();
T* rhs = pointers[j].get();
std::uintptr_t lhs_uint = reinterpret_cast<std::uintptr_t>(lhs);
diff --git a/test/std/utilities/function.objects/func.invoke/invoke_feature_test_macro.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke_feature_test_macro.pass.cpp
new file mode 100644
index 000000000000..aaac98474fcb
--- /dev/null
+++ b/test/std/utilities/function.objects/func.invoke/invoke_feature_test_macro.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// template <class F, class ...Args>
+// result_of_t<F&&(Args&&...)> invoke(F&&, Args&&...);
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 14
+# ifdef __cpp_lib_invoke
+# error Feature test macro should be defined
+# endif
+#else
+# ifndef __cpp_lib_invoke
+# error Feature test macro not defined
+# endif
+# if __cpp_lib_invoke != 201411
+# error __cpp_lib_invoke has the wrong value
+# endif
+#endif
+
+int foo(int) { return 42; }
+
+int main() {
+#if defined(__cpp_lib_invoke)
+ assert(std::invoke(foo, 101) == 42);
+#endif
+} \ No newline at end of file
diff --git a/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp
index c12fa7920974..47a3e1cc5969 100644
--- a/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp
+++ b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp
@@ -138,26 +138,26 @@ inline constexpr CallType operator|(CallType LHS, CallType RHS) {
struct ForwardingCallObject {
template <class ...Args>
- bool operator()(Args&&... args) & {
+ bool operator()(Args&&...) & {
set_call<Args&&...>(CT_NonConst | CT_LValue);
return true;
}
template <class ...Args>
- bool operator()(Args&&... args) const & {
+ bool operator()(Args&&...) const & {
set_call<Args&&...>(CT_Const | CT_LValue);
return true;
}
// Don't allow the call operator to be invoked as an rvalue.
template <class ...Args>
- bool operator()(Args&&... args) && {
+ bool operator()(Args&&...) && {
set_call<Args&&...>(CT_NonConst | CT_RValue);
return true;
}
template <class ...Args>
- bool operator()(Args&&... args) const && {
+ bool operator()(Args&&...) const && {
set_call<Args&&...>(CT_Const | CT_RValue);
return true;
}
@@ -526,7 +526,6 @@ void call_operator_forwarding_test()
assert(Fn::check_call<int&&>(CT_Const | CT_RValue));
}
{ // test multi arg
- int x = 42;
const double y = 3.14;
std::string s = "abc";
obj(42, std::move(y), s, std::string{"foo"});
@@ -554,7 +553,10 @@ void call_operator_noexcept_test()
using T = NoExceptCallable<bool>;
T value(true);
auto ret = std::not_fn(value);
- static_assert(noexcept(!_VSTD::__invoke(value)), "");
+ LIBCPP_STATIC_ASSERT(noexcept(!_VSTD::__invoke(value)), "");
+#if TEST_STD_VER > 14
+ static_assert(noexcept(!std::invoke(value)), "");
+#endif
static_assert(noexcept(ret()), "call should be noexcept");
auto const& cret = ret;
static_assert(noexcept(cret()), "call should be noexcept");
@@ -577,6 +579,19 @@ void call_operator_noexcept_test()
}
}
+void test_lwg2767() {
+ // See http://wg21.link/LWG2767
+ struct Abstract { virtual void f() const = 0; };
+ struct Derived : public Abstract { void f() const {} };
+ struct F { bool operator()(Abstract&&) { return false; } };
+ {
+ Derived d;
+ Abstract &a = d;
+ bool b = std::not_fn(F{})(std::move(a));
+ assert(b);
+ }
+}
+
int main()
{
constructor_tests();
@@ -586,4 +601,5 @@ int main()
call_operator_sfinae_test(); // somewhat of an extension
call_operator_forwarding_test();
call_operator_noexcept_test();
+ test_lwg2767();
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.fail.cpp
new file mode 100644
index 000000000000..e156fa966ac5
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+// XFAIL: c++11, c++14
+
+// <functional>
+
+#include <functional>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct S : public std::function<void()> { using function::function; };
+
+int main() {
+ S f1( [](){} );
+ S f2(std::allocator_arg, std::allocator<int>{}, f1);
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.pass.cpp
new file mode 100644
index 000000000000..5bdf9e98e897
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/derive_from.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
+// REQUIRES-ANY: c++11, c++14
+
+// <functional>
+
+// See https://llvm.org/bugs/show_bug.cgi?id=20002
+
+#include <functional>
+#include <type_traits>
+
+#include "test_macros.h"
+
+using Fn = std::function<void()>;
+struct S : public std::function<void()> { using function::function; };
+
+int main() {
+ S s( [](){} );
+ S f1( s );
+ S f2(std::allocator_arg, std::allocator<int>{}, s);
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
index 58192c928d58..1a9206e0e7f3 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
@@ -12,13 +12,14 @@
// class function<R(ArgTypes...)>
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
-// void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
+// void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
#include <functional>
#include <cstdlib>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
class A
@@ -63,6 +64,9 @@ int main()
{
std::function<int(int)> f1 = A(1);
std::function<int(int)> f2 = A(2);
+#if TEST_STD_VER >= 11
+ static_assert(noexcept(swap(f1, f2)), "" );
+#endif
assert(A::count == 2);
assert(globalMemCounter.checkOutstandingNewEq(2));
assert(f1.target<A>()->id() == 1);
@@ -78,6 +82,9 @@ int main()
{
std::function<int(int)> f1 = A(1);
std::function<int(int)> f2 = g;
+#if TEST_STD_VER >= 11
+ static_assert(noexcept(swap(f1, f2)), "" );
+#endif
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f1.target<A>()->id() == 1);
@@ -93,6 +100,9 @@ int main()
{
std::function<int(int)> f1 = g;
std::function<int(int)> f2 = A(1);
+#if TEST_STD_VER >= 11
+ static_assert(noexcept(swap(f1, f2)), "" );
+#endif
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(*f1.target<int(*)(int)>() == g);
@@ -108,6 +118,9 @@ int main()
{
std::function<int(int)> f1 = g;
std::function<int(int)> f2 = h;
+#if TEST_STD_VER >= 11
+ static_assert(noexcept(swap(f1, f2)), "" );
+#endif
assert(A::count == 0);
assert(globalMemCounter.checkOutstandingNewEq(0));
assert(*f1.target<int(*)(int)>() == g);
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
index 82a6f6c5215e..fd296a7367b8 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
@@ -16,6 +16,7 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
class A
@@ -49,6 +50,17 @@ int A::count = 0;
int g(int) {return 0;}
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) & {}
+};
+#endif
+
int main()
{
assert(globalMemCounter.checkOutstandingNewEq(0));
@@ -91,4 +103,13 @@ int main()
std::function <void()> f(static_cast<void (*)()>(0));
assert(!f);
}
+#if TEST_STD_VER >= 11
+ {
+ using Fn = std::function<void(int, int, int)>;
+ static_assert(std::is_constructible<Fn, LValueCallable&>::value, "");
+ static_assert(std::is_constructible<Fn, LValueCallable>::value, "");
+ static_assert(!std::is_constructible<Fn, RValueCallable&>::value, "");
+ static_assert(!std::is_constructible<Fn, RValueCallable>::value, "");
+ }
+#endif
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
index 11716e7946b0..e927ad42c06b 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
@@ -19,6 +19,7 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
class A
@@ -52,6 +53,17 @@ int A::count = 0;
int g(int) {return 0;}
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) & {}
+};
+#endif
+
int main()
{
assert(globalMemCounter.checkOutstandingNewEq(0));
@@ -95,4 +107,13 @@ int main()
assert(f.target<int(*)(int)>() != 0);
f(1);
}
+#if TEST_STD_VER >= 11
+ {
+ using Fn = std::function<void(int, int, int)>;
+ static_assert(std::is_assignable<Fn&, LValueCallable&>::value, "");
+ static_assert(std::is_assignable<Fn&, LValueCallable>::value, "");
+ static_assert(!std::is_assignable<Fn&, RValueCallable&>::value, "");
+ static_assert(!std::is_assignable<Fn&, RValueCallable>::value, "");
+ }
+#endif
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.fail.cpp
new file mode 100644
index 000000000000..f455f0311847
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// The 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>
+// XFAIL: c++98, c++03, c++11, c++14
+
+// class function<R(ArgTypes...)>
+
+// template<class A> function(allocator_arg_t, const A&);
+
+#include <functional>
+#include <cassert>
+
+#include "min_allocator.h"
+
+int main()
+{
+ std::function<int(int)> f(std::allocator_arg, std::allocator<int>());
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
index f97e34d3f2cb..392dfc1993bc 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
@@ -8,10 +8,13 @@
//===----------------------------------------------------------------------===//
// <functional>
+// REQUIRES-ANY: c++98, c++03, c++11, c++14
// class function<R(ArgTypes...)>
// template<class A> function(allocator_arg_t, const A&);
+//
+// This signature was removed in C++17
#include <functional>
#include <cassert>
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.fail.cpp
new file mode 100644
index 000000000000..24f7fceb877b
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+// XFAIL: c++98, c++03, c++11, c++14
+
+// class function<R(ArgTypes...)>
+
+// template<class F, class A> function(allocator_arg_t, const A&, F);
+//
+// This signature was removed in C++17
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+void foo(int) {}
+
+int main()
+{
+ std::function<void(int)> f(std::allocator_arg, std::allocator<int>(), foo);
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
index 352ecfc602be..8d454723320c 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
// <functional>
+// REQUIRES-ANY: c++98, c++03, c++11, c++14
// class function<R(ArgTypes...)>
@@ -16,11 +17,24 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
#include "test_allocator.h"
#include "count_new.hpp"
#include "../function_types.h"
+
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+ template <class ...Args>
+ void operator()(Args&&...) & {}
+};
+#endif
+
class DummyClass {};
template <class FuncType, class AllocType>
@@ -103,4 +117,14 @@ int main()
non_default_test_allocator<DummyClass> non_default_alloc(42);
test_for_alloc(non_default_alloc);
}
+#if TEST_STD_VER >= 11
+ {
+ using Fn = std::function<void(int, int, int)>;
+ static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, "");
+ static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, "");
+ static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, "");
+ static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, "");
+ }
+#endif
+
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.fail.cpp
new file mode 100644
index 000000000000..9967457ff821
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+// XFAIL: c++98, c++03, c++11, c++14
+
+// class function<R(ArgTypes...)>
+
+// template<class A> function(allocator_arg_t, const A&, const function&);
+//
+// This signature was removed in C++17
+
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ typedef std::function<void(int)> F;
+ F f1;
+ F f2(std::allocator_arg, std::allocator<int>(), f1);
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
index 371eb98de1a9..718aa49341d2 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
// <functional>
+// REQUIRES-ANY: c++98, c++03, c++11, c++14
// class function<R(ArgTypes...)>
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.fail.cpp
new file mode 100644
index 000000000000..cc4ecce75138
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+// XFAIL: c++98, c++03, c++11, c++14
+
+// class function<R(ArgTypes...)>
+
+// template<class A> function(allocator_arg_t, const A&, nullptr_t);
+//
+// This signature was removed in C++17
+
+#include <functional>
+#include <cassert>
+
+#include "min_allocator.h"
+
+int main()
+{
+ std::function<int(int)> f(std::allocator_arg, std::allocator<int>(), nullptr);
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
index 2350f92f0f89..354ad955f207 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
@@ -8,10 +8,13 @@
//===----------------------------------------------------------------------===//
// <functional>
+// REQUIRES-ANY: c++98, c++03, c++11, c++14
// class function<R(ArgTypes...)>
// template<class A> function(allocator_arg_t, const A&, nullptr_t);
+//
+// This signature was removed in C++17
#include <functional>
#include <cassert>
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.fail.cpp
new file mode 100644
index 000000000000..cb9fb9afad2b
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.fail.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+// XFAIL: c++98, c++03, c++11, c++14
+
+// class function<R(ArgTypes...)>
+
+// template<class A> function(allocator_arg_t, const A&, function&&);
+//
+// This signature was removed in C++17
+
+#include <functional>
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+class A
+{
+ int data_[10];
+public:
+ static int count;
+
+ A()
+ {
+ ++count;
+ for (int i = 0; i < 10; ++i)
+ data_[i] = i;
+ }
+
+ A(const A&) {++count;}
+
+ ~A() {--count;}
+
+ int operator()(int i) const
+ {
+ for (int j = 0; j < 10; ++j)
+ i += data_[j];
+ return i;
+ }
+};
+
+int A::count = 0;
+
+int g(int) { return 0; }
+
+int main()
+{
+ {
+ std::function<int(int)> f = A();
+ std::function<int(int)> f2(std::allocator_arg, std::allocator<A>(), std::move(f));
+ }
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
index 403d646f4216..e328481b274d 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
@@ -8,12 +8,15 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
+// REQUIRES-ANY: c++11, c++14
// <functional>
// class function<R(ArgTypes...)>
// template<class A> function(allocator_arg_t, const A&, function&&);
+//
+// This signature was removed in C++17
#include <functional>
#include <memory>
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
index c91eaa2d5674..9b83ddecb974 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
@@ -16,94 +16,123 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
-class A
-{
- int data_[10];
+class A {
+ int data_[10];
+
public:
- static int count;
+ static int count;
- A()
- {
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = i;
- }
+ A() {
+ ++count;
+ for (int i = 0; i < 10; ++i)
+ data_[i] = i;
+ }
- A(const A&) {++count;}
+ A(const A &) { ++count; }
- ~A() {--count;}
+ ~A() { --count; }
- int operator()(int i) const
- {
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
- }
+ int operator()(int i) const {
+ for (int j = 0; j < 10; ++j)
+ i += data_[j];
+ return i;
+ }
};
int A::count = 0;
-int g(int) {return 0;}
+int g0() { return 0; }
+int g(int) { return 0; }
+int g2(int, int) { return 2; }
+int g3(int, int, int) { return 3; }
-int main()
-{
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+int main() {
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f = A();
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
+ assert(f.target<int (*)(int)>() == 0);
std::function<int(int)> f2;
f2 = f;
assert(A::count == 2);
assert(globalMemCounter.checkOutstandingNewEq(2));
assert(f2.target<A>());
- assert(f2.target<int(*)(int)>() == 0);
- }
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ assert(f2.target<int (*)(int)>() == 0);
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f = g;
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>());
+ assert(f.target<int (*)(int)>());
assert(f.target<A>() == 0);
std::function<int(int)> f2;
f2 = f;
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>());
+ assert(f2.target<int (*)(int)>());
assert(f2.target<A>() == 0);
- }
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f;
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>() == 0);
+ assert(f.target<int (*)(int)>() == 0);
assert(f.target<A>() == 0);
std::function<int(int)> f2;
f2 = f;
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>() == 0);
+ assert(f2.target<int (*)(int)>() == 0);
assert(f2.target<A>() == 0);
- }
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ }
+ {
+ typedef std::function<int()> Func;
+ Func f = g0;
+ Func& fr = (f = f);
+ assert(&fr == &f);
+ assert(*f.target<int(*)()>() == g0);
+ }
+ {
+ typedef std::function<int(int)> Func;
+ Func f = g;
+ Func& fr = (f = f);
+ assert(&fr == &f);
+ assert(*f.target<int(*)(int)>() == g);
+ }
+ {
+ typedef std::function<int(int, int)> Func;
+ Func f = g2;
+ Func& fr = (f = f);
+ assert(&fr == &f);
+ assert(*f.target<int(*)(int, int)>() == g2);
+ }
+ {
+ typedef std::function<int(int, int, int)> Func;
+ Func f = g3;
+ Func& fr = (f = f);
+ assert(&fr == &f);
+ assert(*f.target<int(*)(int, int, int)>() == g3);
+ }
+#if TEST_STD_VER >= 11
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f = A();
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
+ assert(f.target<int (*)(int)>() == 0);
std::function<int(int)> f2;
f2 = std::move(f);
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f2.target<A>());
- assert(f2.target<int(*)(int)>() == 0);
+ assert(f2.target<int (*)(int)>() == 0);
assert(f.target<A>() == 0);
- assert(f.target<int(*)(int)>() == 0);
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ assert(f.target<int (*)(int)>() == 0);
+ }
+#endif
}
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 387b371a9331..9d5681a3db76 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
@@ -132,7 +132,7 @@ int main()
assert(A::count == 1);
assert(f2.target<A>() == nullptr);
assert(f2.target<Ref>());
- assert(f.target<Ref>()); // f is unchanged because the target is small
+ LIBCPP_ASSERT(f.target<Ref>()); // f is unchanged because the target is small
}
{
// Test that moving a function constructed from a function pointer
@@ -146,7 +146,7 @@ int main()
std::function<int(int)> f2(std::move(f));
assert(f2.target<A>() == nullptr);
assert(f2.target<Ptr>());
- assert(f.target<Ptr>()); // f is unchanged because the target is small
+ LIBCPP_ASSERT(f.target<Ptr>()); // f is unchanged because the target is small
}
#endif // TEST_STD_VER >= 11
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
index f94e689b2a6b..214c3f7c5d83 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
@@ -18,46 +18,49 @@
#include "count_new.hpp"
-class A
-{
- int data_[10];
+class A {
+ int data_[10];
+
public:
- static int count;
+ static int count;
- explicit A(int j)
- {
- ++count;
- data_[0] = j;
- }
+ explicit A(int j) {
+ ++count;
+ data_[0] = j;
+ }
- A(const A& a)
- {
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = a.data_[i];
- }
+ A(const A &a) {
+ ++count;
+ for (int i = 0; i < 10; ++i)
+ data_[i] = a.data_[i];
+ }
- ~A() {--count;}
+ ~A() { --count; }
- int operator()(int i) const
- {
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
- }
+ int operator()(int i) const {
+ for (int j = 0; j < 10; ++j)
+ i += data_[j];
+ return i;
+ }
+
+ int operator()() const { return -1; }
+ int operator()(int, int) const { return -2; }
+ int operator()(int, int, int) const { return -3; }
- int id() const {return data_[0];}
+ int id() const { return data_[0]; }
};
int A::count = 0;
-int g(int) {return 0;}
-int h(int) {return 1;}
+int g0() { return 0; }
+int g(int) { return 0; }
+int h(int) { return 1; }
+int g2(int, int) { return 2; }
+int g3(int, int, int) { return 3; }
-int main()
-{
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+int main() {
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f1 = A(1);
std::function<int(int)> f2 = A(2);
assert(A::count == 2);
@@ -69,52 +72,122 @@ int main()
assert(globalMemCounter.checkOutstandingNewEq(2));
assert(f1.target<A>()->id() == 2);
assert(f2.target<A>()->id() == 1);
- }
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f1 = A(1);
std::function<int(int)> f2 = g;
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f1.target<A>()->id() == 1);
- assert(*f2.target<int(*)(int)>() == g);
+ assert(*f2.target<int (*)(int)>() == g);
f1.swap(f2);
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(*f1.target<int(*)(int)>() == g);
+ assert(*f1.target<int (*)(int)>() == g);
assert(f2.target<A>()->id() == 1);
- }
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f1 = g;
std::function<int(int)> f2 = A(1);
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(*f1.target<int(*)(int)>() == g);
+ assert(*f1.target<int (*)(int)>() == g);
assert(f2.target<A>()->id() == 1);
f1.swap(f2);
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f1.target<A>()->id() == 1);
- assert(*f2.target<int(*)(int)>() == g);
- }
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
+ assert(*f2.target<int (*)(int)>() == g);
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
std::function<int(int)> f1 = g;
std::function<int(int)> f2 = h;
assert(A::count == 0);
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(*f1.target<int(*)(int)>() == g);
- assert(*f2.target<int(*)(int)>() == h);
+ assert(*f1.target<int (*)(int)>() == g);
+ assert(*f2.target<int (*)(int)>() == h);
f1.swap(f2);
assert(A::count == 0);
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(*f1.target<int(*)(int)>() == h);
- assert(*f2.target<int(*)(int)>() == g);
+ assert(*f1.target<int (*)(int)>() == h);
+ assert(*f2.target<int (*)(int)>() == g);
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ std::function<int(int)> f1 = A(1);
+ assert(A::count == 1);
+ {
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
}
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A::count == 1);
+ assert(f1.target<A>()->id() == 1);
+ }
+ assert(A::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ std::function<int()> f1 = g0;
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(*f1.target<int (*)()>() == g0);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ std::function<int(int, int)> f1 = g2;
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(*f1.target<int (*)(int, int)>() == g2);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ std::function<int(int, int, int)> f1 = g3;
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(*f1.target<int (*)(int, int, int)>() == g3);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ std::function<int()> f1 = A(1);
+ assert(A::count == 1);
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(A::count == 1);
+ assert(f1.target<A>()->id() == 1);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A::count == 0);
+ {
+ std::function<int(int, int)> f1 = A(2);
+ assert(A::count == 1);
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(A::count == 1);
+ assert(f1.target<A>()->id() == 2);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A::count == 0);
+ {
+ std::function<int(int, int, int)> f1 = A(3);
+ assert(A::count == 1);
+ DisableAllocationGuard guard;
+ ((void)guard);
+ f1.swap(f1);
+ assert(A::count == 1);
+ assert(f1.target<A>()->id() == 3);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A::count == 0);
}
diff --git a/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp
index 72f9dc20144d..ac94fa5362e8 100644
--- a/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp
+++ b/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::logical_and<int> F;
@@ -26,7 +28,7 @@ int main()
assert(!f(36, 0));
assert(!f(0, 36));
assert(!f(0, 0));
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::logical_and<> F2;
const F2 f2 = F2();
assert( f2(36, 36));
diff --git a/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp
index 8484625a727c..4f783dd0f23a 100644
--- a/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp
+++ b/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::logical_not<int> F;
@@ -23,7 +25,7 @@ int main()
static_assert((std::is_same<F::result_type, bool>::value), "" );
assert(!f(36));
assert(f(0));
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::logical_not<> F2;
const F2 f2 = F2();
assert(!f2(36));
diff --git a/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp
index 7280504403f4..3c450a05de19 100644
--- a/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp
+++ b/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp
@@ -15,6 +15,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::logical_or<int> F;
@@ -26,7 +28,7 @@ int main()
assert(f(36, 0));
assert(f(0, 36));
assert(!f(0, 0));
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
typedef std::logical_or<> F2;
const F2 f2 = F2();
assert( f2(36, 36));
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 3c00bd20ac64..261a306ca156 100644
--- a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
+++ b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp
@@ -21,7 +21,9 @@
#include <type_traits>
#include <string>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
class MoveOnly
{
MoveOnly(const MoveOnly&);
@@ -55,7 +57,7 @@ int main()
test<int>();
test<double>();
test<std::string>();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test<MoveOnly>();
#endif
}
diff --git a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp
index 8aa2c1df8935..af367789a105 100644
--- a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp
+++ b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11
+
// <functional>
// make sure that we can hash enumeration values
@@ -14,8 +16,6 @@
#include "test_macros.h"
-#if TEST_STD_VER >= 14
-
#include <functional>
#include <cassert>
#include <type_traits>
@@ -59,6 +59,3 @@ int main()
test<Fruits>();
}
-#else
-int main () {}
-#endif
diff --git a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
index 8954f4f3664b..2f3f9bee4bc3 100644
--- a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
+++ b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
@@ -35,11 +35,11 @@ test()
for (int i = 0; i <= 5; ++i)
{
- T t(i);
+ T t(static_cast<T>(i));
if (sizeof(T) <= sizeof(std::size_t))
{
const std::size_t result = h(t);
- LIBCPP_ASSERT(result == t);
+ LIBCPP_ASSERT(result == static_cast<size_t>(t));
((void)result); // Prevent unused warning
}
}
diff --git a/test/std/utilities/function.objects/unord.hash/non_enum.pass.cpp b/test/std/utilities/function.objects/unord.hash/non_enum.pass.cpp
new file mode 100644
index 000000000000..ed173f280d05
--- /dev/null
+++ b/test/std/utilities/function.objects/unord.hash/non_enum.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// Hashing a struct w/o a defined hash should *not* fail, but it should
+// create a type that is not constructible and not callable.
+// See also: http://cplusplus.github.io/LWG/lwg-active.html#2543
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct X {};
+
+int main()
+{
+ using H = std::hash<X>;
+ static_assert(!std::is_default_constructible<H>::value, "");
+ static_assert(!std::is_copy_constructible<H>::value, "");
+ static_assert(!std::is_move_constructible<H>::value, "");
+ static_assert(!std::is_copy_assignable<H>::value, "");
+ static_assert(!std::is_move_assignable<H>::value, "");
+#if TEST_STD_VER > 14
+ static_assert(!std::is_callable<H(X&)>::value, "");
+ static_assert(!std::is_callable<H(X const&)>::value, "");
+#endif
+}
diff --git a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp
index b689160babaa..ed899e7ca268 100644
--- a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp
+++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp
@@ -22,9 +22,11 @@
#include <utility>
+#include "test_macros.h"
+
int main()
{
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
// Should fail to compile, since float is not an integral type
using floatmix = std::integer_sequence<float>;
@@ -34,5 +36,5 @@ int main()
X
-#endif // _LIBCPP_STD_VER > 11
+#endif // TEST_STD_VER > 11
}
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
index af4a3c4dfe7f..192626935f00 100644
--- a/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq.fail.cpp
@@ -14,6 +14,9 @@
// UNSUPPORTED: c++98, c++03, c++11
+// This test hangs during recursive template instantiation with libstdc++
+// UNSUPPORTED: libstdc++
+
#include <utility>
#include <type_traits>
#include <cassert>
diff --git a/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp
index b6431b56d5f0..c3efe72fe7db 100644
--- a/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp
+++ b/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.fail.cpp
@@ -14,5 +14,8 @@
// UNSUPPORTED: c++98, c++03, c++11
+// This test hangs during recursive template instantiation with libstdc++
+// UNSUPPORTED: libstdc++
+
#define _LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE
#include "make_integer_seq.fail.cpp"
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp
index 490fdf5d332b..ab8179c5ab4d 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp
@@ -17,6 +17,7 @@
// };
#include <memory>
+#include <cstdint>
#include <cassert>
template <class T>
@@ -27,12 +28,12 @@ struct A
value_type* allocate(std::size_t n)
{
assert(n == 10);
- return (value_type*)0xDEADBEEF;
+ return reinterpret_cast<value_type*>(static_cast<std::uintptr_t>(0xDEADBEEF));
}
};
int main()
{
A<int> a;
- assert(std::allocator_traits<A<int> >::allocate(a, 10) == (int*)0xDEADBEEF);
+ assert(std::allocator_traits<A<int> >::allocate(a, 10) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF)));
}
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp
index 079db3526ac7..808284261f7d 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp
@@ -17,8 +17,11 @@
// };
#include <memory>
+#include <cstdint>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
struct A
{
@@ -27,7 +30,7 @@ struct A
value_type* allocate(std::size_t n)
{
assert(n == 10);
- return (value_type*)0xDEADBEEF;
+ return reinterpret_cast<value_type*>(static_cast<std::uintptr_t>(0xDEADBEEF));
}
};
@@ -39,22 +42,22 @@ struct B
value_type* allocate(std::size_t n)
{
assert(n == 12);
- return (value_type*)0xEEADBEEF;
+ return reinterpret_cast<value_type*>(static_cast<std::uintptr_t>(0xEEADBEEF));
}
value_type* allocate(std::size_t n, const void* p)
{
assert(n == 11);
assert(p == 0);
- return (value_type*)0xFEADBEEF;
+ return reinterpret_cast<value_type*>(static_cast<std::uintptr_t>(0xFEADBEEF));
}
};
int main()
{
-#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if TEST_STD_VER >= 11
A<int> a;
- assert(std::allocator_traits<A<int> >::allocate(a, 10, nullptr) == (int*)0xDEADBEEF);
-#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ assert(std::allocator_traits<A<int> >::allocate(a, 10, nullptr) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF)));
+#endif
B<int> b;
- assert(std::allocator_traits<B<int> >::allocate(b, 11, nullptr) == (int*)0xFEADBEEF);
+ assert(std::allocator_traits<B<int> >::allocate(b, 11, nullptr) == reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xFEADBEEF)));
}
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp
index 634019758e70..46075f62c6c1 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp
@@ -22,6 +22,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
struct A
{
@@ -36,14 +38,14 @@ struct B
{
typedef T value_type;
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#if TEST_STD_VER >= 11
template <class U, class ...Args>
void construct(U* p, Args&& ...args)
{
++b_construct;
::new ((void*)p) U(std::forward<Args>(args)...);
}
-#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif
};
struct A0
@@ -105,7 +107,7 @@ int main()
std::allocator_traits<A<int> >::construct(a, (A2*)&a2, 'd', 5);
assert(A2::count == 1);
}
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#if TEST_STD_VER >= 11
{
A0::count = 0;
b_construct = 0;
@@ -139,5 +141,5 @@ int main()
assert(A2::count == 1);
assert(b_construct == 1);
}
-#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif
}
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp
index b137dc6d36c3..8176d8b3767a 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp
@@ -17,6 +17,7 @@
// };
#include <memory>
+#include <cstdint>
#include <cassert>
int called = 0;
@@ -28,7 +29,7 @@ struct A
void deallocate(value_type* p, std::size_t n)
{
- assert(p == (value_type*)0xDEADBEEF);
+ assert(p == reinterpret_cast<value_type*>(static_cast<std::uintptr_t>(0xDEADBEEF)));
assert(n == 10);
++called;
}
@@ -37,6 +38,6 @@ struct A
int main()
{
A<int> a;
- std::allocator_traits<A<int> >::deallocate(a, (int*)0xDEADBEEF, 10);
+ std::allocator_traits<A<int> >::deallocate(a, reinterpret_cast<int*>(static_cast<std::uintptr_t>(0xDEADBEEF)), 10);
assert(called == 1);
}
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 54726c929efe..2ee64b8b4a07 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
@@ -22,6 +22,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
struct A
{
@@ -63,7 +65,7 @@ int main()
std::allocator_traits<A<int> >::destroy(a, (A0*)&a0);
assert(A0::count == 1);
}
-#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if TEST_STD_VER >= 11
{
A0::count = 0;
b_destroy = 0;
@@ -76,5 +78,5 @@ int main()
assert(A0::count == 1);
assert(b_destroy == 1);
}
-#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#endif
}
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 bbc6b470174d..d2c9a9826e14 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
@@ -43,7 +43,15 @@ struct B
int main()
{
-#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ {
+ B<int> b;
+ assert(std::allocator_traits<B<int> >::max_size(b) == 100);
+ }
+ {
+ const B<int> b = {};
+ assert(std::allocator_traits<B<int> >::max_size(b) == 100);
+ }
+#if TEST_STD_VER >= 11
{
A<int> a;
assert(std::allocator_traits<A<int> >::max_size(a) ==
@@ -54,16 +62,6 @@ int main()
assert(std::allocator_traits<A<int> >::max_size(a) ==
std::numeric_limits<std::size_t>::max() / sizeof(int));
}
-#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
- {
- B<int> b;
- assert(std::allocator_traits<B<int> >::max_size(b) == 100);
- }
- {
- const B<int> b = {};
- assert(std::allocator_traits<B<int> >::max_size(b) == 100);
- }
-#if TEST_STD_VER >= 11
{
std::allocator<int> a;
static_assert(noexcept(std::allocator_traits<std::allocator<int>>::max_size(a)) == true, "");
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp
index 29fe2be126f3..2e9703037894 100644
--- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp
@@ -22,6 +22,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class T>
struct A
{
@@ -55,7 +57,7 @@ int main()
const A<int> a(0);
assert(std::allocator_traits<A<int> >::select_on_container_copy_construction(a).id == 0);
}
-#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if TEST_STD_VER >= 11
{
B<int> b;
assert(std::allocator_traits<B<int> >::select_on_container_copy_construction(b).id == 100);
@@ -64,5 +66,5 @@ int main()
const B<int> b(0);
assert(std::allocator_traits<B<int> >::select_on_container_copy_construction(b).id == 100);
}
-#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#endif
}
diff --git a/test/std/utilities/memory/allocator.traits/rebind_traits.pass.cpp b/test/std/utilities/memory/allocator.traits/rebind_traits.pass.cpp
index 87da9a0a85da..af4f5bc3fb46 100644
--- a/test/std/utilities/memory/allocator.traits/rebind_traits.pass.cpp
+++ b/test/std/utilities/memory/allocator.traits/rebind_traits.pass.cpp
@@ -19,6 +19,8 @@
#include <memory>
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
struct ReboundA {};
@@ -63,17 +65,17 @@ struct E
int main()
{
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#if TEST_STD_VER >= 11
static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_traits<double>, std::allocator_traits<ReboundA<double> > >::value), "");
static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_traits<double>, std::allocator_traits<ReboundB<double, char> > >::value), "");
static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_traits<double>, std::allocator_traits<C<double> > >::value), "");
static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_traits<double>, std::allocator_traits<D<double, char> > >::value), "");
static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_traits<double>, std::allocator_traits<E<double> > >::value), "");
-#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#else
static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_traits<double>::other, std::allocator_traits<ReboundA<double> > >::value), "");
static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_traits<double>::other, std::allocator_traits<ReboundB<double, char> > >::value), "");
static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_traits<double>::other, std::allocator_traits<C<double> > >::value), "");
static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_traits<double>::other, std::allocator_traits<D<double, char> > >::value), "");
static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_traits<double>::other, std::allocator_traits<E<double> > >::value), "");
-#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#endif
}
diff --git a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
index bd32bc34e7a0..2831399c3047 100644
--- a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
+++ b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
@@ -38,16 +38,38 @@ private:
typedef int allocator_type;
};
+template <bool Expected, class T, class A>
+void
+test()
+{
+ static_assert((std::uses_allocator<T, A>::value == Expected), "");
+#if TEST_STD_VER > 14
+ static_assert((std::uses_allocator_v<T, A> == Expected), "");
+#endif
+}
+
int main()
{
- static_assert((!std::uses_allocator<int, std::allocator<int> >::value), "");
- static_assert(( std::uses_allocator<std::vector<int>, std::allocator<int> >::value), "");
- static_assert((!std::uses_allocator<A, std::allocator<int> >::value), "");
- static_assert((!std::uses_allocator<B, std::allocator<int> >::value), "");
- static_assert(( std::uses_allocator<B, double>::value), "");
- static_assert((!std::uses_allocator<C, decltype(C::allocator_type)>::value), "");
- static_assert((!std::uses_allocator<D, decltype(D::allocator_type)>::value), "");
+ test<false, int, std::allocator<int> >();
+ test<true, std::vector<int>, std::allocator<int> >();
+ test<false, A, std::allocator<int> >();
+ test<false, B, std::allocator<int> >();
+ test<true, B, double>();
+ test<false, C, decltype(C::allocator_type)>();
+ test<false, D, decltype(D::allocator_type)>();
#if TEST_STD_VER >= 11
- static_assert((!std::uses_allocator<E, int>::value), "");
+ test<false, E, int>();
#endif
+
+
+// static_assert((!std::uses_allocator<int, std::allocator<int> >::value), "");
+// static_assert(( std::uses_allocator<std::vector<int>, std::allocator<int> >::value), "");
+// static_assert((!std::uses_allocator<A, std::allocator<int> >::value), "");
+// static_assert((!std::uses_allocator<B, std::allocator<int> >::value), "");
+// static_assert(( std::uses_allocator<B, double>::value), "");
+// static_assert((!std::uses_allocator<C, decltype(C::allocator_type)>::value), "");
+// static_assert((!std::uses_allocator<D, decltype(D::allocator_type)>::value), "");
+// #if TEST_STD_VER >= 11
+// static_assert((!std::uses_allocator<E, int>::value), "");
+// #endif
}
diff --git a/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp
index dc0bdd047c61..768d41878437 100644
--- a/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// <memory>
// allocator:
@@ -16,6 +16,8 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
template <typename T>
void test_max(size_t count)
{
@@ -27,23 +29,19 @@ void test_max(size_t count)
}
}
-int main()
+template <typename T>
+void test()
{
- { // Bug 26812 -- allocating too large
- typedef double T;
- std::allocator<T> a;
- test_max<T> (a.max_size() + 1); // just barely too large
- test_max<T> (a.max_size() * 2); // significantly too large
- test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow
- test_max<T> ((size_t) -1); // way too large
- }
+ // Bug 26812 -- allocating too large
+ std::allocator<T> a;
+ test_max<T> (a.max_size() + 1); // just barely too large
+ test_max<T> (a.max_size() * 2); // significantly too large
+ test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow
+ test_max<T> ((size_t) -1); // way too large
+}
- {
- typedef const double T;
- std::allocator<T> a;
- test_max<T> (a.max_size() + 1); // just barely too large
- test_max<T> (a.max_size() * 2); // significantly too large
- test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow
- test_max<T> ((size_t) -1); // way too large
- }
+int main()
+{
+ test<double>();
+ LIBCPP_ONLY(test<const double>());
}
diff --git a/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp b/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
index cba32103dcd4..7f25e57765d4 100644
--- a/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
@@ -32,6 +32,8 @@
#include <type_traits>
#include <cstddef>
+#include "test_macros.h"
+
int main()
{
static_assert((std::is_same<std::allocator<char>::size_type, std::size_t>::value), "");
@@ -45,7 +47,7 @@ int main()
std::allocator<int> >::value), "");
static_assert((std::is_same<std::allocator< char>::is_always_equal, std::true_type>::value), "");
- static_assert((std::is_same<std::allocator<const char>::is_always_equal, std::true_type>::value), "");
+ LIBCPP_STATIC_ASSERT((std::is_same<std::allocator<const char>::is_always_equal, std::true_type>::value), "");
std::allocator<char> a;
std::allocator<char> a2 = a;
diff --git a/test/std/utilities/memory/pointer.traits/rebind.pass.cpp b/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
index 8716c05f3335..4caf4f650297 100644
--- a/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
+++ b/test/std/utilities/memory/pointer.traits/rebind.pass.cpp
@@ -19,9 +19,11 @@
#include <memory>
#include <type_traits>
+#include "test_macros.h"
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#if TEST_STD_VER >= 11
static_assert((std::is_same<std::pointer_traits<int*>::rebind<double>, double*>::value), "");
#else
static_assert((std::is_same<std::pointer_traits<int*>::rebind<double>::other, double*>::value), "");
diff --git a/test/std/utilities/utility/forward/forward3.fail.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/addressof.temp.fail.cpp
index 7e1e9b38fdc2..81f49eaac39b 100644
--- a/test/std/utilities/utility/forward/forward3.fail.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/addressof.temp.fail.cpp
@@ -7,18 +7,20 @@
//
//===----------------------------------------------------------------------===//
-// test forward
+// <memory>
-#include <utility>
+// template <ObjectType T> T* addressof(T&& r) = delete;
-struct A
-{
-};
+#include <memory>
+#include <cassert>
-A source() {return A();}
-const A csource() {return A();}
+#include "test_macros.h"
int main()
{
- std::forward<A&>(csource()); // error
+#if TEST_STD_VER > 14
+ const int *p = std::addressof<const int>(0);
+#else
+#error
+#endif
}
diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp
index a371f8eda1a8..41f06c519609 100644
--- a/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14
-// XFAIL: gcc
+// XFAIL: gcc-4, gcc-5, gcc-6
// <memory>
diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp
new file mode 100644
index 000000000000..2ad9d04e59b7
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt>
+// void destroy(ForwardIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static void reset() { count = 0; }
+ Counted() { ++count; }
+ Counted(Counted const&) { ++count; }
+ ~Counted() { --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+
+int main()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ std::uninitialized_fill(p, p+N, Counted());
+ assert(Counted::count == 5);
+ std::destroy(p, p+1);
+ p += 1;
+ assert(Counted::count == 4);
+ std::destroy(It(p), It(p + 4));
+ assert(Counted::count == 0);
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
new file mode 100644
index 000000000000..4e67b1eceb57
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.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
+
+// <memory>
+
+// template <class _Tp>
+// void destroy_at(_Tp*);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+struct Counted {
+ static int count;
+ static void reset() { count = 0; }
+ Counted() { ++count; }
+ Counted(Counted const&) { ++count; }
+ ~Counted() { --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+
+struct VCounted {
+ static int count;
+ static void reset() { count = 0; }
+ VCounted() { ++count; }
+ VCounted(VCounted const&) { ++count; }
+ virtual ~VCounted() { --count; }
+ friend void operator&(VCounted) = delete;
+};
+int VCounted::count = 0;
+
+struct DCounted : VCounted {
+ friend void operator&(DCounted) = delete;
+};
+
+int main()
+{
+ {
+ void* mem1 = std::malloc(sizeof(Counted));
+ void* mem2 = std::malloc(sizeof(Counted));
+ assert(mem1 && mem2);
+ assert(Counted::count == 0);
+ Counted* ptr1 = ::new(mem1) Counted();
+ Counted* ptr2 = ::new(mem2) Counted();
+ assert(Counted::count == 2);
+ std::destroy_at(ptr1);
+ assert(Counted::count == 1);
+ std::destroy_at(ptr2);
+ assert(Counted::count == 0);
+ std::free(mem1);
+ std::free(mem2);
+ }
+ {
+ void* mem1 = std::malloc(sizeof(DCounted));
+ void* mem2 = std::malloc(sizeof(DCounted));
+ assert(mem1 && mem2);
+ assert(DCounted::count == 0);
+ DCounted* ptr1 = ::new(mem1) DCounted();
+ DCounted* ptr2 = ::new(mem2) DCounted();
+ assert(DCounted::count == 2);
+ assert(VCounted::count == 2);
+ std::destroy_at(ptr1);
+ assert(VCounted::count == 1);
+ std::destroy_at(ptr2);
+ assert(VCounted::count == 0);
+ std::free(mem1);
+ std::free(mem2);
+ }
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp
new file mode 100644
index 000000000000..d1eaca558a73
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt, class Size>
+// ForwardIt destroy_n(ForwardIt, Size s);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static void reset() { count = 0; }
+ Counted() { ++count; }
+ Counted(Counted const&) { ++count; }
+ ~Counted() { --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+
+int main()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ std::uninitialized_fill(p, p+N, Counted());
+ assert(Counted::count == 5);
+ Counted* np = std::destroy_n(p, 1);
+ assert(np == p+1);
+ assert(Counted::count == 4);
+ p += 1;
+ It it = std::destroy_n(It(p), 4);
+ assert(it == It(p+4));
+ assert(Counted::count == 0);
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp
new file mode 100644
index 000000000000..533d516707e1
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt>
+// void uninitialized_default_construct(ForwardIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted() { ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted() {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { assert(count > 0); --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_default_construct(It(p), It(p+N));
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 0);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+#endif
+}
+
+void test_counted()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ std::uninitialized_default_construct(It(p), It(p+1));
+ assert(Counted::count == 1);
+ assert(Counted::constructed = 1);
+ std::uninitialized_default_construct(It(p+1), It(p+N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+void test_value_initialized()
+{
+ using It = forward_iterator<int*>;
+ const int N = 5;
+ int pool[N] = {-1, -1, -1, -1, -1};
+ int* p = pool;
+ std::uninitialized_default_construct(It(p), It(p+1));
+ assert(pool[0] == -1);
+ assert(pool[1] == -1);
+ std::uninitialized_default_construct(It(p+1), It(p+N));
+ assert(pool[1] == -1);
+ assert(pool[2] == -1);
+ assert(pool[3] == -1);
+ assert(pool[4] == -1);
+}
+
+int main()
+{
+ test_counted();
+ test_value_initialized();
+ test_ctor_throws();
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp
new file mode 100644
index 000000000000..f22a74f1f832
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt>
+// void uninitialized_default_construct(ForwardIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted() { ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { assert(count > 0); --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted() {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { assert(count > 0); --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_default_construct_n(It(p), N);
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 0);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+#endif
+}
+
+void test_counted()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ It e = std::uninitialized_default_construct_n(It(p), 1);
+ assert(e == It(p+1));
+ assert(Counted::count == 1);
+ assert(Counted::constructed = 1);
+ e = std::uninitialized_default_construct_n(It(p+1), 4);
+ assert(e == It(p+N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+void test_value_initialized()
+{
+ using It = forward_iterator<int*>;
+ const int N = 5;
+ int pool[N] = {-1, -1, -1, -1, -1};
+ int* p = pool;
+ auto e = std::uninitialized_default_construct_n(It(p), 1);
+ assert(e == It(p+1));
+ assert(pool[0] == -1);
+ assert(pool[1] == -1);
+ e = std::uninitialized_default_construct_n(It(p+1), 4);
+ assert(e == It(p+N));
+ assert(pool[1] == -1);
+ assert(pool[2] == -1);
+ assert(pool[3] == -1);
+ assert(pool[4] == -1);
+}
+
+
+int main()
+{
+ test_counted();
+ test_value_initialized();
+ test_ctor_throws();
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
new file mode 100644
index 000000000000..c2d860694a75
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt>
+// void uninitialized_value_construct(ForwardIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted() { ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { assert(count > 0); --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted() {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { assert(count > 0); --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_value_construct(It(p), It(p+N));
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 0);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+#endif
+}
+
+void test_counted()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ std::uninitialized_value_construct(It(p), It(p+1));
+ assert(Counted::count == 1);
+ assert(Counted::constructed = 1);
+ std::uninitialized_value_construct(It(p+1), It(p+N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+void test_value_initialized()
+{
+ using It = forward_iterator<int*>;
+ const int N = 5;
+ int pool[N] = {-1, -1, -1, -1, -1};
+ int* p = pool;
+ std::uninitialized_value_construct(It(p), It(p+1));
+ assert(pool[0] == 0);
+ assert(pool[1] == -1);
+ std::uninitialized_value_construct(It(p+1), It(p+N));
+ assert(pool[1] == 0);
+ assert(pool[2] == 0);
+ assert(pool[3] == 0);
+ assert(pool[4] == 0);
+}
+
+int main()
+{
+ test_counted();
+ test_value_initialized();
+ test_ctor_throws();
+}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
new file mode 100644
index 000000000000..323d00f7c9c4
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class ForwardIt>
+// void uninitialized_value_construct(ForwardIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted() { ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { --count; }
+ friend void operator&(Counted) = delete;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted() {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_value_construct_n(It(p), N);
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 3);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+ std::destroy(p, p+3);
+ assert(ThrowsCounted::count == 0);
+#endif
+}
+
+void test_counted()
+{
+ using It = forward_iterator<Counted*>;
+ const int N = 5;
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ It e = std::uninitialized_value_construct_n(It(p), 1);
+ assert(e == It(p+1));
+ assert(Counted::count == 1);
+ assert(Counted::constructed = 1);
+ e = std::uninitialized_value_construct_n(It(p+1), 4);
+ assert(e == It(p+N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+void test_value_initialized()
+{
+ using It = forward_iterator<int*>;
+ const int N = 5;
+ int pool[N] = {-1, -1, -1, -1, -1};
+ int* p = pool;
+ It e = std::uninitialized_value_construct_n(It(p), 1);
+ assert(e == It(p+1));
+ assert(pool[0] == 0);
+ assert(pool[1] == -1);
+ e = std::uninitialized_value_construct_n(It(p+1), 4);
+ assert(e == It(p+N));
+ assert(pool[1] == 0);
+ assert(pool[2] == 0);
+ assert(pool[3] == 0);
+ assert(pool[4] == 0);
+}
+
+int main()
+{
+ test_counted();
+ test_value_initialized();
+} \ No newline at end of file
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
index 1debd6d75ff0..1829dff354d3 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// <memory>
// template <class InputIterator, class ForwardIterator>
@@ -18,13 +17,21 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count_;
static int population_;
int data_;
explicit B() : data_(1) { ++population_; }
- B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+ B(const B &b) {
+ ++count_;
+ if (count_ == 3)
+ TEST_THROW(1);
+ data_ = b.data_;
+ ++population_;
+ }
~B() {data_ = 0; --population_; }
};
@@ -49,6 +56,7 @@ int main()
B* bp = (B*)pool;
B b[N];
assert(B::population_ == N);
+#ifndef TEST_HAS_NO_EXCEPTIONS
try
{
std::uninitialized_copy(b, b+N, bp);
@@ -58,6 +66,7 @@ int main()
{
assert(B::population_ == N);
}
+#endif
B::count_ = 0;
std::uninitialized_copy(b, b+2, bp);
for (int i = 0; i < 2; ++i)
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
index 83aa19471ada..af20cd220291 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// <memory>
// template <class InputIterator, class Size, class ForwardIterator>
@@ -18,13 +17,21 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count_;
static int population_;
int data_;
explicit B() : data_(1) { ++population_; }
- B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+ B(const B &b) {
+ ++count_;
+ if (count_ == 3)
+ TEST_THROW(1);
+ data_ = b.data_;
+ ++population_;
+ }
~B() {data_ = 0; --population_; }
};
@@ -49,6 +56,7 @@ int main()
B* bp = (B*)pool;
B b[N];
assert(B::population_ == N);
+#ifndef TEST_HAS_NO_EXCEPTIONS
try
{
std::uninitialized_copy_n(b, 5, bp);
@@ -58,6 +66,7 @@ int main()
{
assert(B::population_ == N);
}
+#endif
B::count_ = 0;
std::uninitialized_copy_n(b, 2, bp);
for (int i = 0; i < 2; ++i)
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
index 5f90a3792064..862e5be8e363 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// <memory>
// template <class ForwardIterator, class Size, class T>
@@ -17,13 +16,21 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count_;
static int population_;
int data_;
explicit B() : data_(1) { ++population_; }
- B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+ B(const B &b) {
+ ++count_;
+ if (count_ == 3)
+ TEST_THROW(1);
+ data_ = b.data_;
+ ++population_;
+ }
~B() {data_ = 0; --population_; }
};
@@ -47,6 +54,7 @@ int main()
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
assert(B::population_ == 0);
+#ifndef TEST_HAS_NO_EXCEPTIONS
try
{
std::uninitialized_fill_n(bp, 5, B());
@@ -56,6 +64,7 @@ int main()
{
assert(B::population_ == 0);
}
+#endif
B::count_ = 0;
B* r = std::uninitialized_fill_n(bp, 2, B());
assert(r == bp + 2);
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
index 3816a2528688..57438e9cb0d5 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// <memory>
// template <class ForwardIterator, class T>
@@ -18,13 +17,21 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count_;
static int population_;
int data_;
explicit B() : data_(1) { ++population_; }
- B(const B& b) {if (++count_ == 3) throw 1; data_ = b.data_; ++population_; }
+ B(const B &b) {
+ ++count_;
+ if (count_ == 3)
+ TEST_THROW(1);
+ data_ = b.data_;
+ ++population_;
+ }
~B() {data_ = 0; --population_; }
};
@@ -48,6 +55,7 @@ int main()
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
assert(B::population_ == 0);
+#ifndef TEST_HAS_NO_EXCEPTIONS
try
{
std::uninitialized_fill(bp, bp+N, B());
@@ -57,6 +65,7 @@ int main()
{
assert(B::population_ == 0);
}
+#endif
B::count_ = 0;
std::uninitialized_fill(bp, bp+2, B());
for (int i = 0; i < 2; ++i)
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
new file mode 100644
index 000000000000..d7a9542b4c27
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class InputIt, class ForwardIt>
+// ForwardIt uninitialized_move(InputIt, InputIt, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { assert(count > 0); --count; }
+ friend void operator&(Counted) = delete;
+ int value;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted(int&& x) {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ x = 0;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { assert(count > 0); --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ int values[N] = {1, 2, 3, 4, 5};
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_move(values, values + N, It(p));
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 0);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+ assert(values[0] == 0);
+ assert(values[1] == 0);
+ assert(values[2] == 0);
+ assert(values[3] == 4);
+ assert(values[4] == 5);
+#endif
+}
+
+void test_counted()
+{
+ using It = input_iterator<int*>;
+ using FIt = forward_iterator<Counted*>;
+ const int N = 5;
+ int values[N] = {1, 2, 3, 4, 5};
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ auto ret = std::uninitialized_move(It(values), It(values + 1), FIt(p));
+ assert(ret == FIt(p +1));
+ assert(Counted::constructed = 1);
+ assert(Counted::count == 1);
+ assert(p[0].value == 1);
+ assert(values[0] == 0);
+ ret = std::uninitialized_move(It(values+1), It(values+N), FIt(p+1));
+ assert(ret == FIt(p + N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ assert(p[1].value == 2);
+ assert(p[2].value == 3);
+ assert(p[3].value == 4);
+ assert(p[4].value == 5);
+ assert(values[1] == 0);
+ assert(values[2] == 0);
+ assert(values[3] == 0);
+ assert(values[4] == 0);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+int main() {
+ test_counted();
+ test_ctor_throws();
+} \ No newline at end of file
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
new file mode 100644
index 000000000000..f27e5726135f
--- /dev/null
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <memory>
+
+// template <class InputIt, class Size, class ForwardIt>
+// pair<InputIt, ForwardIt> uninitialized_move_n(InputIt, Size, ForwardIt);
+
+#include <memory>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct Counted {
+ static int count;
+ static int constructed;
+ static void reset() { count = constructed = 0; }
+ explicit Counted(int&& x) : value(x) { x = 0; ++count; ++constructed; }
+ Counted(Counted const&) { assert(false); }
+ ~Counted() { assert(count > 0); --count; }
+ friend void operator&(Counted) = delete;
+ int value;
+};
+int Counted::count = 0;
+int Counted::constructed = 0;
+
+struct ThrowsCounted {
+ static int count;
+ static int constructed;
+ static int throw_after;
+ static void reset() { throw_after = count = constructed = 0; }
+ explicit ThrowsCounted(int&& x) {
+ ++constructed;
+ if (throw_after > 0 && --throw_after == 0) {
+ TEST_THROW(1);
+ }
+ ++count;
+ x = 0;
+ }
+ ThrowsCounted(ThrowsCounted const&) { assert(false); }
+ ~ThrowsCounted() { assert(count > 0); --count; }
+ friend void operator&(ThrowsCounted) = delete;
+};
+int ThrowsCounted::count = 0;
+int ThrowsCounted::constructed = 0;
+int ThrowsCounted::throw_after = 0;
+
+void test_ctor_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using It = forward_iterator<ThrowsCounted*>;
+ const int N = 5;
+ int values[N] = {1, 2, 3, 4, 5};
+ alignas(ThrowsCounted) char pool[sizeof(ThrowsCounted)*N] = {};
+ ThrowsCounted* p = (ThrowsCounted*)pool;
+ try {
+ ThrowsCounted::throw_after = 4;
+ std::uninitialized_move_n(values, N, It(p));
+ assert(false);
+ } catch (...) {}
+ assert(ThrowsCounted::count == 0);
+ assert(ThrowsCounted::constructed == 4); // forth construction throws
+ assert(values[0] == 0);
+ assert(values[1] == 0);
+ assert(values[2] == 0);
+ assert(values[3] == 4);
+ assert(values[4] == 5);
+#endif
+}
+
+void test_counted()
+{
+ using It = input_iterator<int*>;
+ using FIt = forward_iterator<Counted*>;
+ const int N = 5;
+ int values[N] = {1, 2, 3, 4, 5};
+ alignas(Counted) char pool[sizeof(Counted)*N] = {};
+ Counted* p = (Counted*)pool;
+ auto ret = std::uninitialized_move_n(It(values), 1, FIt(p));
+ assert(ret.first == It(values +1));
+ assert(ret.second == FIt(p +1));
+ assert(Counted::constructed = 1);
+ assert(Counted::count == 1);
+ assert(p[0].value == 1);
+ assert(values[0] == 0);
+ ret = std::uninitialized_move_n(It(values+1), N-1, FIt(p+1));
+ assert(ret.first == It(values+N));
+ assert(ret.second == FIt(p + N));
+ assert(Counted::count == 5);
+ assert(Counted::constructed == 5);
+ assert(p[1].value == 2);
+ assert(p[2].value == 3);
+ assert(p[3].value == 4);
+ assert(p[4].value == 5);
+ assert(values[1] == 0);
+ assert(values[2] == 0);
+ assert(values[3] == 0);
+ assert(values[4] == 0);
+ std::destroy(p, p+N);
+ assert(Counted::count == 0);
+}
+
+int main()
+{
+ test_counted();
+ test_ctor_throws();
+} \ No newline at end of file
diff --git a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
index 914802423ce7..3df8dd0eded0 100644
--- a/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
+++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp
@@ -13,6 +13,7 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
#include <MoveOnly.h>
int A_constructed = 0;
@@ -46,7 +47,7 @@ int main()
assert(A_constructed == i+1);
}
}
-#if _LIBCPP_STD_VER >= 14
+#if TEST_STD_VER >= 14
{
typedef MoveOnly S;
typedef std::aligned_storage<3*sizeof(S), std::alignment_of<S>::value>::type
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
index a611b1a12f05..2949d6310c59 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
@@ -24,4 +24,5 @@ int main()
{
std::default_delete<int[]> d1;
std::default_delete<const int[]> d2 = d1;
+ ((void)d2);
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/null_ctor.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/null_ctor.pass.cpp
index 6d752b9951a5..50389978e8ab 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/null_ctor.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/null_ctor.pass.cpp
@@ -16,6 +16,8 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
class Deleter
{
int state_;
@@ -36,9 +38,18 @@ int main()
Deleter d;
assert(d.state() == 0);
{
+ std::unique_ptr<int[], Deleter&> p(nullptr, d);
+ assert(p.get() == 0);
+ assert(&p.get_deleter() == &d);
+ }
+#if defined(_LIBCPP_VERSION)
+ {
+ // The standard only requires the constructor accept nullptr, but libc++
+ // also supports the literal 0.
std::unique_ptr<int[], Deleter&> p(0, d);
assert(p.get() == 0);
assert(&p.get_deleter() == &d);
}
+#endif
assert(d.state() == 0);
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
index 5720d3bd288f..89b6fa248845 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
@@ -38,7 +38,7 @@ source1()
return std::unique_ptr<A[]>(new A[3]);
}
-void sink1(std::unique_ptr<A[]> p)
+void sink1(std::unique_ptr<A[]>)
{
}
@@ -48,7 +48,7 @@ source2()
return std::unique_ptr<A[], Deleter<A[]> >(new A[3]);
}
-void sink2(std::unique_ptr<A[], Deleter<A[]> > p)
+void sink2(std::unique_ptr<A[], Deleter<A[]> >)
{
}
@@ -59,7 +59,7 @@ source3()
return std::unique_ptr<A[], NCDeleter<A[]>&>(new A[3], d);
}
-void sink3(std::unique_ptr<A[], NCDeleter<A[]>&> p)
+void sink3(std::unique_ptr<A[], NCDeleter<A[]>&>)
{
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp
index 2b0b5f0d945d..3de556563f97 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp
@@ -42,7 +42,9 @@ int main()
assert(A::count == 0);
{ // LWG#2520 says that nullptr is a valid input as well as null
+#ifdef _LIBCPP_VERSION
std::unique_ptr<A[], Deleter<A[]> > s1(NULL, Deleter<A[]>());
+#endif
std::unique_ptr<A[], Deleter<A[]> > s2(nullptr, Deleter<A[]>());
}
assert(A::count == 0);
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert08.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert08.fail.cpp
index e14bba0763c5..016eadcb2460 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert08.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert08.fail.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// unique_ptr
@@ -46,17 +48,10 @@ template <class T>
class Deleter
{
int state_;
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(const Deleter&);
Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
Deleter& operator=(Deleter&& r)
{
@@ -64,20 +59,9 @@ public:
r.state_ = 0;
return *this;
}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter() : state_(5) {}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class U>
Deleter(Deleter<U>&& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
@@ -87,12 +71,7 @@ private:
template <class U>
Deleter(const Deleter<U>& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
public:
int state() const {return state_;}
void set_state(int i) {state_ = i;}
@@ -102,17 +81,6 @@ public:
int main()
{
- {
- const std::unique_ptr<B, Deleter<B> > s(new B);
- A* p = s.get();
- std::unique_ptr<A, Deleter<A> > s2(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 0);
- }
- assert(A::count == 0);
- assert(B::count == 0);
+ const std::unique_ptr<B, Deleter<B> > s;
+ std::unique_ptr<A, Deleter<A> > s2(s); // expected-error {{no matching constructor}}
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert11.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert11.fail.cpp
index bcf94a978144..1b8bb736df20 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert11.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert11.fail.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// unique_ptr
@@ -47,16 +49,9 @@ class Deleter
{
int state_;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(const Deleter&);
Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
Deleter& operator=(Deleter&& r)
{
@@ -64,20 +59,9 @@ public:
r.state_ = 0;
return *this;
}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter() : state_(5) {}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class U>
Deleter(Deleter<U>&& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
@@ -87,12 +71,7 @@ private:
template <class U>
Deleter(const Deleter<U>& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
public:
int state() const {return state_;}
void set_state(int i) {state_ = i;}
@@ -102,17 +81,6 @@ public:
int main()
{
- {
- const std::unique_ptr<B, Deleter<B> > s(new B);
- A* p = s.get();
- std::unique_ptr<A, Deleter<A> > s2 = s;
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 0);
- }
- assert(A::count == 0);
- assert(B::count == 0);
+ const std::unique_ptr<B, Deleter<B> > s;
+ std::unique_ptr<A, Deleter<A> > s2 = s; // expected-error {{no viable conversion}}
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
index 93956bcae663..20275de603e2 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// shared_ptr
@@ -42,7 +44,6 @@ int A::count = 0;
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
@@ -119,5 +120,4 @@ int main()
}
assert(B::count == 0);
assert(A::count == 0);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
index 4194890dda2d..4a85633a89ad 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// shared_ptr
@@ -42,7 +44,6 @@ int A::count = 0;
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
@@ -119,5 +120,4 @@ int main()
}
assert(B::count == 0);
assert(A::count == 0);
-#endif // _LIBCXX_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
index 41aeb04a5feb..2e6441d66316 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// <memory>
// template<class D, class A> shared_ptr(nullptr_t, D d, A a);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
index 85fc5e930544..009b4cfc00f9 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// UNSUPPORTED: sanitizer-new-delete
// <memory>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
index c72847791778..388599bd7015 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// <memory>
// template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
index 70af2964113d..7b40d6df2164 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// UNSUPPORTED: sanitizer-new-delete
// <memory>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
index 2fa975eca833..182d5f4a4937 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: libcpp-no-exceptions
// UNSUPPORTED: sanitizer-new-delete
// <memory>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp
index f041d9451a6d..ea0720404b48 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// shared_ptr
@@ -17,6 +19,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count;
@@ -66,24 +70,24 @@ int main()
std::shared_ptr<B> pB(std::move(pA));
assert(B::count == 1);
assert(A::count == 1);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
assert(pB.use_count() == 1);
assert(pA.use_count() == 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#else
assert(pB.use_count() == 2);
assert(pA.use_count() == 2);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
assert(p == pB.get());
}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
assert(pA.use_count() == 0);
assert(B::count == 0);
assert(A::count == 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#else
assert(pA.use_count() == 1);
assert(B::count == 1);
assert(A::count == 1);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
}
assert(B::count == 0);
assert(A::count == 0);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp
index b89178e201cf..257d3ce19be3 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <memory>
// shared_ptr
@@ -16,6 +18,8 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct A
{
static int count;
@@ -37,22 +41,22 @@ int main()
A* p = pA.get();
std::shared_ptr<A> pA2(std::move(pA));
assert(A::count == 1);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
assert(pA.use_count() == 0);
assert(pA2.use_count() == 1);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#else
assert(pA.use_count() == 2);
assert(pA2.use_count() == 2);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
assert(pA2.get() == p);
}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
assert(pA.use_count() == 0);
assert(A::count == 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#else
assert(pA.use_count() == 1);
assert(A::count == 1);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
}
assert(A::count == 0);
{
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
index 5c424f5c7428..877577c9ce58 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// UNSUPPORTED: sanitizer-new-delete
// <memory>
@@ -63,6 +62,7 @@ int main()
assert(p.get() == raw_ptr);
assert(ptr.get() == 0);
}
+#ifndef TEST_HAS_NO_EXCEPTIONS
assert(A::count == 0);
{
std::unique_ptr<A> ptr(new A);
@@ -86,6 +86,7 @@ int main()
#endif
}
}
+#endif
assert(A::count == 0);
{ // LWG 2399
fn(std::unique_ptr<int>(new int));
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
index 35a7d077b424..830aa5bbca4c 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// <memory>
// shared_ptr
@@ -17,6 +16,8 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count;
@@ -42,6 +43,7 @@ int A::count = 0;
int main()
{
+#ifndef TEST_HAS_NO_EXCEPTIONS
{
std::weak_ptr<A> wp;
try
@@ -54,6 +56,7 @@ int main()
}
assert(A::count == 0);
}
+#endif
{
std::shared_ptr<A> sp0(new A);
std::weak_ptr<A> wp(sp0);
@@ -63,6 +66,7 @@ int main()
assert(A::count == 1);
}
assert(A::count == 0);
+#ifndef TEST_HAS_NO_EXCEPTIONS
{
std::shared_ptr<A> sp0(new A);
std::weak_ptr<A> wp(sp0);
@@ -77,4 +81,5 @@ int main()
}
}
assert(A::count == 0);
+#endif
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
index 8cb972b0c1a1..8d782716b94f 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
@@ -16,6 +16,7 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
struct A
@@ -65,7 +66,7 @@ int main()
assert(p2.get());
}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
nc = globalMemCounter.outstanding_new;
{
char c = 'e';
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
index 75bf3df90aa3..90f958e26852 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
@@ -18,6 +18,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
struct B
{
static int count;
@@ -55,7 +57,7 @@ int C::count = 0;
template <class T>
std::weak_ptr<T> source (std::shared_ptr<T> p) { return std::weak_ptr<T>(p); }
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
template <class T>
void sink (std::weak_ptr<T> &&) {}
#endif
@@ -100,7 +102,7 @@ int main()
assert(B::count == 0);
assert(A::count == 0);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
{
std::shared_ptr<A> ps(new A);
std::weak_ptr<A> pA = source(ps);
diff --git a/test/std/utilities/meta/meta.help/integral_constant.pass.cpp b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp
index 335305a28236..51a837e4e032 100644
--- a/test/std/utilities/meta/meta.help/integral_constant.pass.cpp
+++ b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp
@@ -14,6 +14,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::integral_constant<int, 5> _5;
@@ -26,7 +28,7 @@ int main()
assert(_5() == 5);
#endif
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert ( _5{}() == 5, "" );
static_assert ( std::true_type{}(), "" );
#endif
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_all_extents.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_all_extents.pass.cpp
index 28bbedee1749..f7902a2be775 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_all_extents.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_all_extents.pass.cpp
@@ -13,13 +13,15 @@
#include <type_traits>
+#include "test_macros.h"
+
enum Enum {zero, one_};
template <class T, class U>
void test_remove_all_extents()
{
static_assert((std::is_same<typename std::remove_all_extents<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::remove_all_extents_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_extent.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_extent.pass.cpp
index c688c26b9a5b..aa175d9ebc8c 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_extent.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.arr/remove_extent.pass.cpp
@@ -13,13 +13,15 @@
#include <type_traits>
+#include "test_macros.h"
+
enum Enum {zero, one_};
template <class T, class U>
void test_remove_extent()
{
static_assert((std::is_same<typename std::remove_extent<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::remove_extent_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_const.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_const.pass.cpp
index 19b1fb4d01b3..ef1aa8acbc68 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_const.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_const.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_add_const_imp()
{
static_assert((std::is_same<typename std::add_const<T>::type, const U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::add_const_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_cv.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_cv.pass.cpp
index 4905e518e12a..c0c2483e4c40 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_cv.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_cv.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_add_cv_imp()
{
static_assert((std::is_same<typename std::add_cv<T>::type, const volatile U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::add_cv_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_volatile.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_volatile.pass.cpp
index 7a12c44a2c6e..f29fb06cd807 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/add_volatile.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/add_volatile.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_add_volatile_imp()
{
static_assert((std::is_same<typename std::add_volatile<T>::type, volatile U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::add_volatile_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_const.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_const.pass.cpp
index cd2faf786d80..426d22d29f67 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_const.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_const.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_remove_const_imp()
{
static_assert((std::is_same<typename std::remove_const<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::remove_const_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_cv.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_cv.pass.cpp
index 3f6405c8280c..a6ce05756ef6 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_cv.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_cv.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_remove_cv_imp()
{
static_assert((std::is_same<typename std::remove_cv<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::remove_cv_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_volatile.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_volatile.pass.cpp
index 6258a9039b40..90b8d4bcbea2 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_volatile.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.cv/remove_volatile.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_remove_volatile_imp()
{
static_assert((std::is_same<typename std::remove_volatile<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::remove_volatile_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
index ae849ca54558..43f23f5ccc80 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
@@ -13,12 +13,14 @@
#include <type_traits>
+#include "test_macros.h"
+
int main()
{
#ifndef _LIBCPP_HAS_NO_VARIADICS
{
typedef std::aligned_union<10, char >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, char>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 1, "");
@@ -26,7 +28,7 @@ int main()
}
{
typedef std::aligned_union<10, short >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, short>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 2, "");
@@ -34,7 +36,7 @@ int main()
}
{
typedef std::aligned_union<10, int >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, int>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 4, "");
@@ -42,7 +44,7 @@ int main()
}
{
typedef std::aligned_union<10, double >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, double>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 8, "");
@@ -50,7 +52,7 @@ int main()
}
{
typedef std::aligned_union<10, short, char >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, short, char>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 2, "");
@@ -58,7 +60,7 @@ int main()
}
{
typedef std::aligned_union<10, char, short >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<10, char, short>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 2, "");
@@ -66,7 +68,7 @@ int main()
}
{
typedef std::aligned_union<2, int, char, short >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<2, int, char, short>, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 4, "");
@@ -74,7 +76,7 @@ int main()
}
{
typedef std::aligned_union<2, char, int, short >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<2, char, int, short >, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 4, "");
@@ -82,7 +84,7 @@ int main()
}
{
typedef std::aligned_union<2, char, short, int >::type T1;
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(std::is_same<std::aligned_union_t<2, char, short, int >, T1>::value, "" );
#endif
static_assert(std::alignment_of<T1>::value == 4, "");
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
index e8611253c5d4..61523e4872d4 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
@@ -12,6 +12,7 @@
// common_type
#include <type_traits>
+#include <memory>
#include "test_macros.h"
@@ -30,15 +31,198 @@ namespace std
{
typedef S<T> type;
};
+
+ template <class T>
+ struct common_type< ::S<T>, T> {
+ typedef S<T> type;
+ };
+
+ template <> struct common_type< ::S<long>, long> {};
+ template <> struct common_type<long, ::S<long> > {};
}
#if TEST_STD_VER >= 11
-template <class T, class U, class = void>
-struct no_common_type : std::true_type {};
+template <class Tp>
+struct always_bool_imp { using type = bool; };
+template <class Tp> using always_bool = typename always_bool_imp<Tp>::type;
+
+template <class ...Args>
+constexpr auto no_common_type_imp(int)
+ -> always_bool<typename std::common_type<Args...>::type>
+ { return false; }
+
+template <class ...Args>
+constexpr bool no_common_type_imp(long) { return true; }
+
+template <class ...Args>
+using no_common_type = std::integral_constant<bool, no_common_type_imp<Args...>(0)>;
+
+template <class Tp>
+using Decay = typename std::decay<Tp>::type;
+
+template <class ...Args>
+using CommonType = typename std::common_type<Args...>::type;
+
+template <class T1, class T2>
+struct TernaryOpImp {
+ static_assert(std::is_same<Decay<T1>, T1>::value, "must be same");
+ static_assert(std::is_same<Decay<T2>, T2>::value, "must be same");
+ using type = typename std::decay<
+ decltype(false ? std::declval<T1>() : std::declval<T2>())
+ >::type;
+};
+
+template <class T1, class T2>
+using TernaryOp = typename TernaryOpImp<T1, T2>::type;
+
+// -- If sizeof...(T) is zero, there shall be no member type.
+void test_bullet_one() {
+ static_assert(no_common_type<>::value, "");
+}
+
+// If sizeof...(T) is one, let T0 denote the sole type constituting the pack T.
+// The member typedef-name type shall denote the same type as decay_t<T0>.
+void test_bullet_two() {
+ static_assert(std::is_same<CommonType<void>, void>::value, "");
+ static_assert(std::is_same<CommonType<int>, int>::value, "");
+ static_assert(std::is_same<CommonType<int const>, int>::value, "");
+ static_assert(std::is_same<CommonType<int volatile[]>, int volatile*>::value, "");
+ static_assert(std::is_same<CommonType<void(&)()>, void(*)()>::value, "");
+}
+
+template <class T, class U, class Expect>
+void test_bullet_three_one_imp() {
+ using DT = Decay<T>;
+ using DU = Decay<U>;
+ static_assert(!std::is_same<T, DT>::value || !std::is_same<U, DU>::value, "");
+ static_assert(std::is_same<CommonType<T, U>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<U, T>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<T, U>, CommonType<DT, DU>>::value, "");
+}
+
+// (3.3)
+// -- If sizeof...(T) is two, let the first and second types constituting T be
+// denoted by T1 and T2, respectively, and let D1 and D2 denote the same types
+// as decay_t<T1> and decay_t<T2>, respectively.
+// (3.3.1)
+// -- If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false, let C
+// denote the same type, if any, as common_type_t<D1, D2>.
+void test_bullet_three_one() {
+ // Test that the user provided specialization of common_type is used after
+ // decaying T1.
+ {
+ using T1 = S<int> const;
+ using T2 = int;
+ test_bullet_three_one_imp<T1, T2, S<int> >();
+ }
+ // Test a user provided specialization that does not provide a typedef.
+ {
+ using T1 = ::S<long> const;
+ using T2 = long;
+ static_assert(no_common_type<T1, T2>::value, "");
+ static_assert(no_common_type<T2, T1>::value, "");
+ }
+ // Test that the ternary operator is not applied when the types are the
+ // same.
+ {
+ using T1 = const void;
+ using Expect = void;
+ static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, "");
+ }
+ {
+ using T1 = int const[];
+ using Expect = int const*;
+ static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, "");
+ }
+}
-template <class T, class U>
-struct no_common_type<T, U, typename std::conditional<false,
- typename std::common_type<T, U>::type, void>::type> : std::false_type {};
+// (3.3)
+// -- If sizeof...(T) is two, let the first and second types constituting T be
+// denoted by T1 and T2, respectively, and let D1 and D2 denote the same types
+// as decay_t<T1> and decay_t<T2>, respectively.
+// (3.3.1)
+// -- If [...]
+// (3.3.2)
+// -- Otherwise, let C denote the same type, if any, as
+// decay_t<decltype(false ? declval<D1>() : declval<D2>())>
+void test_bullet_three_two() {
+ {
+ using T1 = int const*;
+ using T2 = int*;
+ using Expect = TernaryOp<T1, T2>;
+ static_assert(std::is_same<CommonType<T1, T2>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<T2, T1>, Expect>::value, "");
+ }
+ // Test that there is no ::type member when the ternary op is ill-formed
+ {
+ using T1 = int;
+ using T2 = void;
+ static_assert(no_common_type<T1, T2>::value, "");
+ static_assert(no_common_type<T2, T1>::value, "");
+ }
+ {
+ using T1 = int;
+ using T2 = X<int>;
+ static_assert(no_common_type<T1, T2>::value, "");
+ static_assert(no_common_type<T2, T1>::value, "");
+ }
+ // Test that the ternary operator is not applied when the types are the
+ // same.
+ {
+ using T1 = void;
+ using Expect = void;
+ static_assert(std::is_same<CommonType<T1, T1>, Expect>::value, "");
+ static_assert(std::is_same<CommonType<T1, T1>, CommonType<T1>>::value, "");
+ }
+}
+
+// (3.4)
+// -- If sizeof...(T) is greater than two, let T1, T2, and R, respectively,
+// denote the first, second, and (pack of) remaining types constituting T.
+// Let C denote the same type, if any, as common_type_t<T1, T2>. If there is
+// such a type C, the member typedef-name type shall denote the
+// same type, if any, as common_type_t<C, R...>. Otherwise, there shall be
+// no member type.
+void test_bullet_four() {
+ { // test that there is no ::type member
+ static_assert(no_common_type<int, E>::value, "");
+ static_assert(no_common_type<int, int, E>::value, "");
+ static_assert(no_common_type<int, int, E, int>::value, "");
+ static_assert(no_common_type<int, int, int, E>::value, "");
+ }
+}
+
+
+// The example code specified in Note B for common_type
+namespace note_b_example {
+
+using PF1 = bool (&)();
+using PF2 = short (*)(long);
+
+struct S {
+ operator PF2() const;
+ double operator()(char, int&);
+ void fn(long) const;
+ char data;
+};
+
+using PMF = void (S::*)(long) const;
+using PMD = char S::*;
+
+using std::is_same;
+using std::result_of;
+using std::unique_ptr;
+
+static_assert(is_same<typename result_of<S(int)>::type, short>::value, "Error!");
+static_assert(is_same<typename result_of<S&(unsigned char, int&)>::type, double>::value, "Error!");
+static_assert(is_same<typename result_of<PF1()>::type, bool>::value, "Error!");
+static_assert(is_same<typename result_of<PMF(unique_ptr<S>, int)>::type, void>::value, "Error!");
+static_assert(is_same<typename result_of<PMD(S)>::type, char&&>::value, "Error!");
+static_assert(is_same<typename result_of<PMD(const S*)>::type, const char&>::value, "Error!");
+
+} // namespace note_b_example
#endif // TEST_STD_VER >= 11
int main()
@@ -89,14 +273,15 @@ int main()
static_assert((std::is_same<std::common_type<volatile void, void>::type, void>::value), "");
static_assert((std::is_same<std::common_type<const void, const void>::type, void>::value), "");
-#if TEST_STD_VER >= 11
- static_assert((no_common_type<void, int>::value), "");
- static_assert((no_common_type<int, void>::value), "");
- static_assert((no_common_type<int, E>::value), "");
- static_assert((no_common_type<int, X<int> >::value), "");
-#endif // TEST_STD_VER >= 11
-
static_assert((std::is_same<std::common_type<int, S<int> >::type, S<int> >::value), "");
static_assert((std::is_same<std::common_type<int, S<int>, S<int> >::type, S<int> >::value), "");
static_assert((std::is_same<std::common_type<int, int, S<int> >::type, S<int> >::value), "");
+
+#if TEST_STD_VER >= 11
+ test_bullet_one();
+ test_bullet_two();
+ test_bullet_three_one();
+ test_bullet_three_two();
+ test_bullet_four();
+#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/conditional.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/conditional.pass.cpp
index ac11e3a4ce86..7de0a0737905 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/conditional.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/conditional.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
int main()
{
static_assert((std::is_same<std::conditional<true, char, int>::type, char>::value), "");
static_assert((std::is_same<std::conditional<false, char, int>::type, int>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::conditional_t<true, char, int>, char>::value), "");
static_assert((std::is_same<std::conditional_t<false, char, int>, int>::value), "");
#endif
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/decay.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/decay.pass.cpp
index bd8ae0e297bc..bcd839849453 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/decay.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/decay.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T, class U>
void test_decay()
{
static_assert((std::is_same<typename std::decay<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::decay_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if.pass.cpp
index eb72b0f393b3..a9b1e1be1274 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
int main()
{
static_assert((std::is_same<std::enable_if<true>::type, void>::value), "");
static_assert((std::is_same<std::enable_if<true, int>::type, int>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::enable_if_t<true>, void>::value), "");
static_assert((std::is_same<std::enable_if_t<true, int>, int>::value), "");
#endif
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
index 1d7b23c19222..410e47e03bcc 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
@@ -21,14 +21,19 @@ enum F { W = UINT_MAX };
int main()
{
+#if !defined(_WIN32) || defined(__MINGW32__)
+ typedef unsigned ExpectUnsigned;
+#else
+ typedef int ExpectUnsigned; // MSVC's ABI doesn't follow the Standard
+#endif
static_assert((std::is_same<std::underlying_type<E>::type, int>::value),
"E has the wrong underlying type");
- static_assert((std::is_same<std::underlying_type<F>::type, unsigned>::value),
+ static_assert((std::is_same<std::underlying_type<F>::type, ExpectUnsigned>::value),
"F has the wrong underlying type");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::underlying_type_t<E>, int>::value), "");
- static_assert((std::is_same<std::underlying_type_t<F>, unsigned>::value), "");
+ static_assert((std::is_same<std::underlying_type_t<F>, ExpectUnsigned>::value), "");
#endif
#if TEST_STD_VER >= 11
@@ -36,7 +41,7 @@ int main()
static_assert((std::is_same<std::underlying_type<G>::type, char>::value),
"G has the wrong underlying type");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::underlying_type_t<G>, char>::value), "");
#endif
#endif // TEST_STD_VER >= 11
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp
index fc147c37b1ac..373bad7d6e3c 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// type_traits
// add_rvalue_reference
@@ -16,8 +18,6 @@
#include <type_traits>
#include "test_macros.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
template <class T, class U>
void test_add_rvalue_reference()
{
@@ -44,13 +44,11 @@ void test_function1()
static_assert((std::is_same<std::add_rvalue_reference_t<F>, F>::value), "");
#endif
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
struct Foo {};
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
test_add_rvalue_reference<void, void>();
test_add_rvalue_reference<int, int&&>();
test_add_rvalue_reference<int[3], int(&&)[3]>();
@@ -63,22 +61,17 @@ int main()
// LWG 2101 specifically talks about add_rvalue_reference and functions.
// The term of art is "a referenceable type", which a cv- or ref-qualified function is not.
test_function0<void()>();
-#if TEST_STD_VER >= 11
test_function1<void() const>();
test_function1<void() &>();
test_function1<void() &&>();
test_function1<void() const &>();
test_function1<void() const &&>();
-#endif
// But a cv- or ref-qualified member function *is* "a referenceable type"
test_function0<void (Foo::*)()>();
-#if TEST_STD_VER >= 11
test_function0<void (Foo::*)() const>();
test_function0<void (Foo::*)() &>();
test_function0<void (Foo::*)() &&>();
test_function0<void (Foo::*)() const &>();
test_function0<void (Foo::*)() const &&>();
-#endif
-#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp
index e335bd19ef2d..1f9ec2476b50 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp
@@ -37,11 +37,11 @@ int main()
test_remove_reference<int*&, int*>();
test_remove_reference<const int*&, const int*>();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_remove_reference<int&&, int>();
test_remove_reference<const int&&, const int>();
test_remove_reference<int(&&)[3], int[3]>();
test_remove_reference<int*&&, int*>();
test_remove_reference<const int*&&, const int*>();
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.sign/make_signed.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.sign/make_signed.pass.cpp
index eb8e31c76e10..06f6e6152aec 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.sign/make_signed.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.sign/make_signed.pass.cpp
@@ -13,9 +13,15 @@
#include <type_traits>
+#include "test_macros.h"
+
enum Enum {zero, one_};
+#if TEST_STD_VER >= 11
+enum BigEnum : unsigned long long // MSVC's ABI doesn't follow the Standard
+#else
enum BigEnum
+#endif
{
bigzero,
big = 0xFFFFFFFFFFFFFFFFULL
@@ -32,7 +38,7 @@ template <class T, class U>
void test_make_signed()
{
static_assert((std::is_same<typename std::make_signed<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::make_signed_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.sign/make_unsigned.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.sign/make_unsigned.pass.cpp
index 984440193fa6..3d152f6049e9 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.sign/make_unsigned.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.sign/make_unsigned.pass.cpp
@@ -13,9 +13,15 @@
#include <type_traits>
+#include "test_macros.h"
+
enum Enum {zero, one_};
+#if TEST_STD_VER >= 11
+enum BigEnum : unsigned long long // MSVC's ABI doesn't follow the Standard
+#else
enum BigEnum
+#endif
{
bigzero,
big = 0xFFFFFFFFFFFFFFFFULL
@@ -32,7 +38,7 @@ template <class T, class U>
void test_make_unsigned()
{
static_assert((std::is_same<typename std::make_unsigned<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<std::make_unsigned_t<T>, U>::value), "");
#endif
}
diff --git a/test/std/utilities/meta/meta.unary.prop.query/void_t_feature_test_macro.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/void_t_feature_test_macro.pass.cpp
new file mode 100644
index 000000000000..f188c098c034
--- /dev/null
+++ b/test/std/utilities/meta/meta.unary.prop.query/void_t_feature_test_macro.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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// void_t
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 14
+# ifdef __cpp_lib_void_t
+# error Feature test macro should not be defined!
+# endif
+#else
+# ifndef __cpp_lib_void_t
+# error Feature test macro is not defined
+# endif
+# if __cpp_lib_void_t != 201411
+# error Feature test macro has the wrong value
+# endif
+#endif
+
+int main()
+{
+#if defined(__cpp_lib_void_t)
+ static_assert(std::is_same_v<std::void_t<int>, void>, "");
+#endif
+}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp
index 13cad58c0ef3..5154a1d12936 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp
@@ -13,11 +13,13 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
void test_lvalue_ref()
{
static_assert(!std::is_void<T>::value, "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(!std::is_null_pointer<T>::value, "");
#endif
static_assert(!std::is_integral<T>::value, "");
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp
index b0edea37e8e8..cdaf713ac928 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp
@@ -14,11 +14,13 @@
#define _LIBCPP_HAS_NO_VARIADICS
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
void test_member_function_pointer_imp()
{
static_assert(!std::is_void<T>::value, "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(!std::is_null_pointer<T>::value, "");
#endif
static_assert(!std::is_integral<T>::value, "");
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp
index 99fd2887981f..23d391b490e5 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// type_traits
// rvalue_ref
@@ -39,11 +41,9 @@ struct incomplete_type;
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
test_rvalue_ref<int&&>();
test_rvalue_ref<const int&&>();
// LWG#2582
static_assert(!std::is_rvalue_reference<incomplete_type>::value, "");
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/rvalue_ref.pass.cpp
index 7563c2fd5850..b9b28fd8c3f1 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.comp/rvalue_ref.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/rvalue_ref.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// type_traits
// rvalue_ref
@@ -27,8 +29,6 @@ void test_rvalue_ref()
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
test_rvalue_ref<int&&>();
test_rvalue_ref<const int&&>();
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
index b734a1aa60d8..f4736e713422 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
@@ -43,7 +43,7 @@ void test_is_not_assignable()
struct D;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
struct C
{
template <class U>
@@ -59,6 +59,8 @@ struct E
template <typename T>
struct X { T t; };
+struct Incomplete;
+
int main()
{
test_is_assignable<int&, int&> ();
@@ -67,7 +69,7 @@ int main()
test_is_assignable<B, A> ();
test_is_assignable<void*&, void*> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_is_assignable<E, int> ();
test_is_not_assignable<int, int&> ();
@@ -80,4 +82,5 @@ int main()
// pointer to incomplete template type
test_is_assignable<X<D>*&, X<D>*> ();
+ test_is_not_assignable<Incomplete&, Incomplete const&>();
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp
index 9f8fdc7fc635..f6ae401533a9 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp
@@ -14,9 +14,18 @@
// template <class T, class... Args>
// struct is_constructible;
+// MODULES_DEFINES: _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
+#define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
#include <type_traits>
#include "test_macros.h"
+#if TEST_STD_VER >= 11 && defined(_LIBCPP_VERSION)
+#define LIBCPP11_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
+#else
+#define LIBCPP11_STATIC_ASSERT(...) ((void)0)
+#endif
+
+
struct A
{
explicit A(int);
@@ -27,6 +36,9 @@ private:
A(char);
};
+struct Base {};
+struct Derived : public Base {};
+
class Abstract
{
virtual void foo() = 0;
@@ -37,10 +49,38 @@ class AbstractDestructor
virtual ~AbstractDestructor() = 0;
};
+struct PrivateDtor {
+ PrivateDtor(int) {}
+private:
+ ~PrivateDtor() {}
+};
+
+struct S {
+ template <class T>
+#if TEST_STD_VER >= 11
+ explicit
+#endif
+ operator T () const;
+};
+
+template <class To>
+struct ImplicitTo {
+ operator To();
+};
+
+#if TEST_STD_VER >= 11
+template <class To>
+struct ExplicitTo {
+ explicit operator To ();
+};
+#endif
+
+
template <class T>
void test_is_constructible()
{
static_assert( (std::is_constructible<T>::value), "");
+ LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T>::type::value), "");
#if TEST_STD_VER > 14
static_assert( std::is_constructible_v<T>, "");
#endif
@@ -50,6 +90,7 @@ template <class T, class A0>
void test_is_constructible()
{
static_assert(( std::is_constructible<T, A0>::value), "");
+ LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0>::type::value), "");
#if TEST_STD_VER > 14
static_assert(( std::is_constructible_v<T, A0>), "");
#endif
@@ -59,6 +100,7 @@ template <class T, class A0, class A1>
void test_is_constructible()
{
static_assert(( std::is_constructible<T, A0, A1>::value), "");
+ LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0, A1>::type::value), "");
#if TEST_STD_VER > 14
static_assert(( std::is_constructible_v<T, A0, A1>), "");
#endif
@@ -68,6 +110,7 @@ template <class T>
void test_is_not_constructible()
{
static_assert((!std::is_constructible<T>::value), "");
+ LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T>::type::value), "");
#if TEST_STD_VER > 14
static_assert((!std::is_constructible_v<T>), "");
#endif
@@ -77,13 +120,28 @@ template <class T, class A0>
void test_is_not_constructible()
{
static_assert((!std::is_constructible<T, A0>::value), "");
+ LIBCPP11_STATIC_ASSERT((!std::__libcpp_is_constructible<T, A0>::type::value), "");
#if TEST_STD_VER > 14
static_assert((!std::is_constructible_v<T, A0>), "");
#endif
}
+#if TEST_STD_VER >= 11
+template <class T = int, class = decltype(static_cast<T&&>(std::declval<double&>()))>
+constexpr bool clang_disallows_valid_static_cast_test(int) { return false; };
+
+constexpr bool clang_disallows_valid_static_cast_test(long) { return true; }
+
+static constexpr bool clang_disallows_valid_static_cast_bug =
+ clang_disallows_valid_static_cast_test(0);
+#endif
+
+
int main()
{
+ typedef Base B;
+ typedef Derived D;
+
test_is_constructible<int> ();
test_is_constructible<int, const int> ();
test_is_constructible<A, int> ();
@@ -97,17 +155,138 @@ int main()
test_is_constructible<A, char> ();
#endif
test_is_not_constructible<A, void> ();
+ test_is_not_constructible<int, void()>();
+ test_is_not_constructible<int, void(&)()>();
+ test_is_not_constructible<int, void() const>();
+ test_is_not_constructible<int&, void>();
+ test_is_not_constructible<int&, void()>();
+ test_is_not_constructible<int&, void() const>();
+ test_is_not_constructible<int&, void(&)()>();
+
test_is_not_constructible<void> ();
+ test_is_not_constructible<const void> (); // LWG 2738
+ test_is_not_constructible<volatile void> ();
+ test_is_not_constructible<const volatile void> ();
test_is_not_constructible<int&> ();
test_is_not_constructible<Abstract> ();
test_is_not_constructible<AbstractDestructor> ();
+ test_is_constructible<int, S>();
+ test_is_not_constructible<int&, S>();
-// LWG 2560 -- postpone this test until bots updated
-// test_is_not_constructible<void()> ();
-#if TEST_STD_VER > 11
-// test_is_not_constructible<void() const> ();
-// test_is_not_constructible<void() volatile> ();
-// test_is_not_constructible<void() &> ();
-// test_is_not_constructible<void() &&> ();
+ test_is_constructible<void(&)(), void(&)()>();
+ test_is_constructible<void(&)(), void()>();
+#if TEST_STD_VER >= 11
+ test_is_constructible<void(&&)(), void(&&)()>();
+ test_is_constructible<void(&&)(), void()>();
+ test_is_constructible<void(&&)(), void(&)()>();
+#endif
+
+#if TEST_STD_VER >= 11
+ test_is_constructible<int const&, int>();
+ test_is_constructible<int const&, int&&>();
+
+ test_is_constructible<int&&, double&>();
+ test_is_constructible<void(&)(), void(&&)()>();
+
+ test_is_not_constructible<int&, int>();
+ test_is_not_constructible<int&, int const&>();
+ test_is_not_constructible<int&, int&&>();
+
+ test_is_constructible<int&&, int>();
+ test_is_constructible<int&&, int&&>();
+ test_is_not_constructible<int&&, int&>();
+ test_is_not_constructible<int&&, int const&&>();
+
+ test_is_constructible<Base, Derived>();
+ test_is_constructible<Base&, Derived&>();
+ test_is_not_constructible<Derived&, Base&>();
+ test_is_constructible<Base const&, Derived const&>();
+ test_is_not_constructible<Derived const&, Base const&>();
+ test_is_not_constructible<Derived const&, Base>();
+
+ test_is_constructible<Base&&, Derived>();
+ test_is_constructible<Base&&, Derived&&>();
+ test_is_not_constructible<Derived&&, Base&&>();
+ test_is_not_constructible<Derived&&, Base>();
+
+ // test that T must also be destructible
+ test_is_constructible<PrivateDtor&, PrivateDtor&>();
+ test_is_not_constructible<PrivateDtor, int>();
+
+ test_is_not_constructible<void() const, void() const>();
+ test_is_not_constructible<void() const, void*>();
+
+ test_is_constructible<int&, ImplicitTo<int&>>();
+ test_is_constructible<const int&, ImplicitTo<int&&>>();
+ test_is_constructible<int&&, ImplicitTo<int&&>>();
+ test_is_constructible<const int&, ImplicitTo<int>>();
+
+ test_is_not_constructible<B&&, B&>();
+ test_is_not_constructible<B&&, D&>();
+ test_is_constructible<B&&, ImplicitTo<D&&>>();
+ test_is_constructible<B&&, ImplicitTo<D&&>&>();
+ test_is_constructible<int&&, double&>();
+ test_is_constructible<const int&, ImplicitTo<int&>&>();
+ test_is_constructible<const int&, ImplicitTo<int&>>();
+ test_is_constructible<const int&, ExplicitTo<int&>&>();
+ test_is_constructible<const int&, ExplicitTo<int&>>();
+
+ test_is_constructible<const int&, ExplicitTo<int&>&>();
+ test_is_constructible<const int&, ExplicitTo<int&>>();
+ test_is_constructible<int&, ExplicitTo<int&>>();
+ test_is_constructible<const int&, ExplicitTo<int&&>>();
+
+ // Binding through reference-compatible type is required to perform
+ // direct-initialization as described in [over.match.ref] p. 1 b. 1:
+ test_is_constructible<int&, ExplicitTo<int&>>();
+ test_is_constructible<const int&, ExplicitTo<int&&>>();
+
+ static_assert(std::is_constructible<int&&, ExplicitTo<int&&>>::value, "");
+#ifdef __clang__
+#if defined(CLANG_TEST_VER) && CLANG_TEST_VER < 400
+ static_assert(clang_disallows_valid_static_cast_bug, "bug still exists");
+#endif
+ // FIXME Clang disallows this construction because it thinks that
+ // 'static_cast<int&&>(declval<ExplicitTo<int&&>>())' is ill-formed.
+ LIBCPP_STATIC_ASSERT(
+ clang_disallows_valid_static_cast_bug !=
+ std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
+#else
+ static_assert(clang_disallows_valid_static_cast_bug == false, "");
+ LIBCPP_STATIC_ASSERT(std::__libcpp_is_constructible<int&&, ExplicitTo<int&&>>::value, "");
+#endif
+
+#ifdef __clang__
+ // FIXME Clang and GCC disagree on the validity of this expression.
+ test_is_constructible<const int&, ExplicitTo<int>>();
+ static_assert(std::is_constructible<int&&, ExplicitTo<int>>::value, "");
+ LIBCPP_STATIC_ASSERT(
+ clang_disallows_valid_static_cast_bug !=
+ std::__libcpp_is_constructible<int&&, ExplicitTo<int>>::value, "");
+#else
+ test_is_not_constructible<const int&, ExplicitTo<int>>();
+ test_is_not_constructible<int&&, ExplicitTo<int>>();
+#endif
+
+ // Binding through temporary behaves like copy-initialization,
+ // see [dcl.init.ref] p. 5, very last sub-bullet:
+ test_is_not_constructible<const int&, ExplicitTo<double&&>>();
+ test_is_not_constructible<int&&, ExplicitTo<double&&>>();
+
+
+// TODO: Remove this workaround once Clang <= 3.7 are no longer used regularly.
+// In those compiler versions the __is_constructible builtin gives the wrong
+// results for abominable function types.
+#if (defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER < 703) \
+ || (defined(TEST_CLANG_VER) && TEST_CLANG_VER < 308)
+#define WORKAROUND_CLANG_BUG
+#endif
+#if !defined(WORKAROUND_CLANG_BUG)
+ test_is_not_constructible<void()>();
+ test_is_not_constructible<void() const> ();
+ test_is_not_constructible<void() volatile> ();
+ test_is_not_constructible<void() &> ();
+ test_is_not_constructible<void() &&> ();
#endif
+#endif // TEST_STD_VER >= 11
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
index ac8b80bbd3a4..06cf8007889d 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
@@ -74,12 +74,10 @@ int main()
test_is_copy_assignable<NotEmpty> ();
test_is_copy_assignable<Empty> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_is_not_copy_assignable<const int> ();
test_is_not_copy_assignable<int[]> ();
test_is_not_copy_assignable<int[3]> ();
-#endif
-#if TEST_STD_VER >= 11
test_is_not_copy_assignable<B> ();
#endif
test_is_not_copy_assignable<void> ();
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp
index 318147e5d4a3..22755dc33dc3 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp
@@ -92,15 +92,35 @@ int main()
test_is_default_constructible<int*>();
test_is_default_constructible<const int*>();
test_is_default_constructible<char[3]>();
+ test_is_default_constructible<char[5][3]>();
+
test_is_default_constructible<NotEmpty>();
test_is_default_constructible<bit_zero>();
test_is_not_default_constructible<void>();
test_is_not_default_constructible<int&>();
test_is_not_default_constructible<char[]>();
+ test_is_not_default_constructible<char[][3]>();
+
test_is_not_default_constructible<Abstract>();
test_is_not_default_constructible<NoDefaultConstructor>();
#if TEST_STD_VER >= 11
test_is_not_default_constructible<B>();
+ test_is_not_default_constructible<int&&>();
+
+// TODO: Remove this workaround once Clang <= 3.7 are no longer used regularly.
+// In those compiler versions the __is_constructible builtin gives the wrong
+// results for abominable function types.
+#if (defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER < 703) \
+ || (defined(TEST_CLANG_VER) && TEST_CLANG_VER < 308)
+#define WORKAROUND_CLANG_BUG
+#endif
+#if !defined(WORKAROUND_CLANG_BUG)
+ test_is_not_default_constructible<void()>();
+ test_is_not_default_constructible<void() const> ();
+ test_is_not_default_constructible<void() volatile> ();
+ test_is_not_default_constructible<void() &> ();
+ test_is_not_default_constructible<void() &&> ();
+#endif
#endif
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
index 410c1db7244d..7be76f4fa96a 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
@@ -11,6 +11,14 @@
// is_empty
+// T is a non-union class type with:
+// no non-static data members,
+// no unnamed bit-fields of non-zero length,
+// no virtual member functions,
+// no virtual base classes,
+// and no base class B for which is_empty_v<B> is false.
+
+
#include <type_traits>
#include "test_macros.h"
@@ -44,22 +52,33 @@ void test_is_not_empty()
#endif
}
-class Empty
-{
-};
+class Empty {};
+struct NotEmpty { int foo; };
-class NotEmpty
+class VirtualFn
{
- virtual ~NotEmpty();
+ virtual ~VirtualFn();
};
union Union {};
+struct EmptyBase : public Empty {};
+struct VirtualBase : virtual Empty {};
+struct NotEmptyBase : public NotEmpty {};
+
+struct StaticMember { static int foo; };
+struct NonStaticMember { int foo; };
+
struct bit_zero
{
int : 0;
};
+struct bit_one
+{
+ int : 1;
+};
+
int main()
{
test_is_not_empty<void>();
@@ -72,7 +91,14 @@ int main()
test_is_not_empty<char[]>();
test_is_not_empty<Union>();
test_is_not_empty<NotEmpty>();
+ test_is_not_empty<VirtualFn>();
+ test_is_not_empty<VirtualBase>();
+ test_is_not_empty<NotEmptyBase>();
+ test_is_not_empty<NonStaticMember>();
+// test_is_not_empty<bit_one>();
test_is_empty<Empty>();
+ test_is_empty<EmptyBase>();
+ test_is_empty<StaticMember>();
test_is_empty<bit_zero>();
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
index 613c1123e3fa..6209bc7b1483 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
@@ -63,7 +63,7 @@ int main()
test_is_move_assignable<NotEmpty> ();
test_is_move_assignable<Empty> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_is_not_move_assignable<const int> ();
test_is_not_move_assignable<int[]> ();
test_is_not_move_assignable<int[3]> ();
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
index 07c283bf8890..e81f8d4f43c4 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_move_constructible.pass.cpp
@@ -62,7 +62,7 @@ struct A
struct B
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
B(B&&);
#endif
};
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
index 9d629dc7ef46..3349a9d3a968 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
@@ -50,7 +50,7 @@ int main()
{
test_is_nothrow_assignable<int&, int&> ();
test_is_nothrow_assignable<int&, int> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_is_nothrow_assignable<int&, double> ();
#endif
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
index 8200b468fe3a..f36b80cac17c 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
@@ -92,7 +92,7 @@ struct C
void operator=(C&); // not const
};
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
struct Tuple {
Tuple(Empty&&) noexcept {}
};
@@ -104,15 +104,14 @@ int main()
test_is_nothrow_constructible<int, const int&> ();
test_is_nothrow_constructible<Empty> ();
test_is_nothrow_constructible<Empty, const Empty&> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616.
-#endif
test_is_not_nothrow_constructible<A, int> ();
test_is_not_nothrow_constructible<A, int, double> ();
test_is_not_nothrow_constructible<A> ();
test_is_not_nothrow_constructible<C> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
+ test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616.
+
static_assert(!std::is_constructible<Tuple&, Empty>::value, "");
test_is_not_nothrow_constructible<Tuple &, Empty> (); // See bug #19616.
#endif
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
index 408231f6057f..b23a5e45f287 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
@@ -59,7 +59,7 @@ int main()
!std::is_nothrow_swappable_with<A&, A&>::value, "");
}
{
- // test that hetrogenius swap is allowed only if both 'swap(A, B)' and
+ // test that heterogeneous swap is allowed only if both 'swap(A, B)' and
// 'swap(B, A)' are valid.
static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
diff --git a/test/std/utilities/utility/forward/forward2.fail.cpp b/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
index 9ff07233fee8..e3c7bb5ad27b 100644
--- a/test/std/utilities/utility/forward/forward2.fail.cpp
+++ b/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp
@@ -7,19 +7,17 @@
//
//===----------------------------------------------------------------------===//
-// test forward
+// UNSUPPORTED: c++98, c++03, c++11, c++14
-#include <utility>
+// <optional>
-struct A
-{
-};
+// class bad_optional_access is default constructible
-A source() {return A();}
-const A csource() {return A();}
+#include <optional>
+#include <type_traits>
int main()
{
- const A ca = A();
- std::forward<A&>(ca); // error
+ using std::bad_optional_access;
+ bad_optional_access ex;
}
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
new file mode 100644
index 000000000000..85e36d2c107d
--- /dev/null
+++ b/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// class bad_optional_access : public logic_error
+
+#include <optional>
+#include <type_traits>
+
+int main()
+{
+ using std::bad_optional_access;
+
+ static_assert(std::is_base_of<std::logic_error, bad_optional_access>::value, "");
+ static_assert(std::is_convertible<bad_optional_access*, std::logic_error*>::value, "");
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
new file mode 100644
index 000000000000..b54a08f5575b
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator==(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator==(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator == ( const X &lhs, const X &rhs )
+ { return lhs.i_ == rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( !(o1 == T(1)), "" );
+ static_assert ( (o2 == T(1)), "" );
+ static_assert ( !(o3 == T(1)), "" );
+ static_assert ( (o3 == T(2)), "" );
+ static_assert ( (o3 == val), "" );
+
+ static_assert ( !(T(1) == o1), "" );
+ static_assert ( (T(1) == o2), "" );
+ static_assert ( !(T(1) == o3), "" );
+ static_assert ( (T(2) == o3), "" );
+ static_assert ( (val == o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
new file mode 100644
index 000000000000..064114fb9db2
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator>(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator>(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator > ( const X &lhs, const X &rhs )
+ { return lhs.i_ > rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( !(o1 > T(1)), "" );
+ static_assert ( !(o2 > T(1)), "" ); // equal
+ static_assert ( (o3 > T(1)), "" );
+ static_assert ( !(o2 > val), "" );
+ static_assert ( !(o3 > val), "" ); // equal
+ static_assert ( !(o3 > T(3)), "" );
+
+ static_assert ( (T(1) > o1), "" );
+ static_assert ( !(T(1) > o2), "" ); // equal
+ static_assert ( !(T(1) > o3), "" );
+ static_assert ( (val > o2), "" );
+ static_assert ( !(val > o3), "" ); // equal
+ static_assert ( (T(3) > o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
new file mode 100644
index 000000000000..663686cdf347
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator>=(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator>=(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator >= ( const X &lhs, const X &rhs )
+ { return lhs.i_ >= rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( !(o1 >= T(1)), "" );
+ static_assert ( (o2 >= T(1)), "" ); // equal
+ static_assert ( (o3 >= T(1)), "" );
+ static_assert ( !(o2 >= val), "" );
+ static_assert ( (o3 >= val), "" ); // equal
+ static_assert ( !(o3 >= T(3)), "" );
+
+ static_assert ( (T(1) >= o1), "" );
+ static_assert ( (T(1) >= o2), "" ); // equal
+ static_assert ( !(T(1) >= o3), "" );
+ static_assert ( (val >= o2), "" );
+ static_assert ( (val >= o3), "" ); // equal
+ static_assert ( (T(3) >= o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
new file mode 100644
index 000000000000..05ac5eb12b48
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator<=(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator<=(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator <= ( const X &lhs, const X &rhs )
+ { return lhs.i_ <= rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( (o1 <= T(1)), "" );
+ static_assert ( (o2 <= T(1)), "" ); // equal
+ static_assert ( !(o3 <= T(1)), "" );
+ static_assert ( (o2 <= val), "" );
+ static_assert ( (o3 <= val), "" ); // equal
+ static_assert ( (o3 <= T(3)), "" );
+
+ static_assert ( !(T(1) <= o1), "" );
+ static_assert ( (T(1) <= o2), "" ); // equal
+ static_assert ( (T(1) <= o3), "" );
+ static_assert ( !(val <= o2), "" );
+ static_assert ( (val <= o3), "" ); // equal
+ static_assert ( !(T(3) <= o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
new file mode 100644
index 000000000000..d1891a286d7b
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator<(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator<(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator < ( const X &lhs, const X &rhs )
+ { return lhs.i_ < rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( (o1 < T(1)), "" );
+ static_assert ( !(o2 < T(1)), "" ); // equal
+ static_assert ( !(o3 < T(1)), "" );
+ static_assert ( (o2 < val), "" );
+ static_assert ( !(o3 < val), "" ); // equal
+ static_assert ( (o3 < T(3)), "" );
+
+ static_assert ( !(T(1) < o1), "" );
+ static_assert ( !(T(1) < o2), "" ); // equal
+ static_assert ( (T(1) < o3), "" );
+ static_assert ( !(val < o2), "" );
+ static_assert ( !(val < o3), "" ); // equal
+ static_assert ( !(T(3) < o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp b/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
new file mode 100644
index 000000000000..ae2ff808fb25
--- /dev/null
+++ b/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator!=(const optional<T>& x, const T& v);
+// template <class T> constexpr bool operator!=(const T& v, const optional<T>& x);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator != ( const X &lhs, const X &rhs )
+ { return lhs.i_ != rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr T val(2);
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+ constexpr O o3{val}; // engaged
+
+ static_assert ( (o1 != T(1)), "" );
+ static_assert ( !(o2 != T(1)), "" );
+ static_assert ( (o3 != T(1)), "" );
+ static_assert ( !(o3 != T(2)), "" );
+ static_assert ( !(o3 != val), "" );
+
+ static_assert ( (T(1) != o1), "" );
+ static_assert ( !(T(1) != o2), "" );
+ static_assert ( (T(1) != o3), "" );
+ static_assert ( !(T(2) != o3), "" );
+ static_assert ( !(val != o3), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.hash/hash.pass.cpp b/test/std/utilities/optional/optional.hash/hash.pass.cpp
new file mode 100644
index 000000000000..dfdd07ddf452
--- /dev/null
+++ b/test/std/utilities/optional/optional.hash/hash.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> struct hash<optional<T>>;
+
+#include <optional>
+#include <string>
+#include <memory>
+#include <cassert>
+
+
+int main()
+{
+ using std::optional;
+ const std::size_t nullopt_hash =
+ std::hash<optional<double>>{}(optional<double>{});
+
+ {
+ typedef int T;
+ optional<T> opt;
+ assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
+ opt = 2;
+ assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
+ }
+ {
+ typedef std::string T;
+ optional<T> opt;
+ assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
+ opt = std::string("123");
+ assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
+ }
+ {
+ typedef std::unique_ptr<int> T;
+ optional<T> opt;
+ assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
+ opt = std::unique_ptr<int>(new int(3));
+ assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/equal.pass.cpp b/test/std/utilities/optional/optional.nullops/equal.pass.cpp
new file mode 100644
index 000000000000..a87a87f877fc
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/equal.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
+// <optional>
+
+// template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( (nullopt == o1), "" );
+ static_assert ( !(nullopt == o2), "" );
+ static_assert ( (o1 == nullopt), "" );
+ static_assert ( !(o2 == nullopt), "" );
+
+ static_assert (noexcept(nullopt == o1), "");
+ static_assert (noexcept(o1 == nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/greater.pass.cpp b/test/std/utilities/optional/optional.nullops/greater.pass.cpp
new file mode 100644
index 000000000000..3986a0a92658
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/greater.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
+// <optional>
+
+// template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( !(nullopt > o1), "" );
+ static_assert ( !(nullopt > o2), "" );
+ static_assert ( !(o1 > nullopt), "" );
+ static_assert ( (o2 > nullopt), "" );
+
+ static_assert (noexcept(nullopt > o1), "");
+ static_assert (noexcept(o1 > nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp b/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp
new file mode 100644
index 000000000000..9f2427273476
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/greater_equal.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
+// <optional>
+
+// template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( (nullopt >= o1), "" );
+ static_assert ( !(nullopt >= o2), "" );
+ static_assert ( (o1 >= nullopt), "" );
+ static_assert ( (o2 >= nullopt), "" );
+
+ static_assert (noexcept(nullopt >= o1), "");
+ static_assert (noexcept(o1 >= nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp b/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp
new file mode 100644
index 000000000000..8e73247b9d6e
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <optional>
+
+// template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( (nullopt <= o1), "" );
+ static_assert ( (nullopt <= o2), "" );
+ static_assert ( (o1 <= nullopt), "" );
+ static_assert ( !(o2 <= nullopt), "" );
+
+ static_assert (noexcept(nullopt <= o1), "");
+ static_assert (noexcept(o1 <= nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/less_than.pass.cpp b/test/std/utilities/optional/optional.nullops/less_than.pass.cpp
new file mode 100644
index 000000000000..39a8e4a39363
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/less_than.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
+// <optional>
+
+// template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( !(nullopt < o1), "" );
+ static_assert ( (nullopt < o2), "" );
+ static_assert ( !(o1 < nullopt), "" );
+ static_assert ( !(o2 < nullopt), "" );
+
+ static_assert (noexcept(nullopt < o1), "");
+ static_assert (noexcept(o1 < nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp b/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp
new file mode 100644
index 000000000000..1c96dd42e808
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullops/not_equal.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
+// <optional>
+
+// template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept;
+// template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ {
+ typedef int T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2{1}; // engaged
+
+ static_assert ( !(nullopt != o1), "" );
+ static_assert ( (nullopt != o2), "" );
+ static_assert ( !(o1 != nullopt), "" );
+ static_assert ( (o2 != nullopt), "" );
+
+ static_assert (noexcept(nullopt != o1), "");
+ static_assert (noexcept(o1 != nullopt), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp b/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
new file mode 100644
index 000000000000..86da5054a708
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// struct nullopt_t{see below};
+
+#include <optional>
+
+using std::optional;
+using std::nullopt_t;
+
+int main()
+{
+ // I roughly interpret LWG2736 as "it shall not be possible to copy-list-initialize nullopt_t with an
+ // empty braced-init-list."
+ nullopt_t foo = {};
+}
diff --git a/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp b/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
new file mode 100644
index 000000000000..84bb29fabac8
--- /dev/null
+++ b/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// struct nullopt_t{see below};
+// constexpr nullopt_t nullopt(unspecified);
+
+#include <optional>
+#include <type_traits>
+
+using std::optional;
+using std::nullopt_t;
+using std::nullopt;
+
+constexpr
+int
+test(const nullopt_t&)
+{
+ return 3;
+}
+
+int main()
+{
+ static_assert((std::is_class<nullopt_t>::value), "");
+ static_assert((std::is_empty<nullopt_t>::value), "");
+ static_assert((std::is_literal_type<nullopt_t>::value), "");
+ static_assert((!std::is_default_constructible<nullopt_t>::value), "");
+
+ static_assert(test(nullopt) == 3, "");
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp
new file mode 100644
index 000000000000..1207e24150ff
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp
@@ -0,0 +1,273 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class U> optional<T>& operator=(U&& v);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+#include <memory>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+struct ThrowAssign {
+ static int dtor_called;
+ ThrowAssign() = default;
+ ThrowAssign(int) { TEST_THROW(42); }
+ ThrowAssign& operator=(int) {
+ TEST_THROW(42);
+ }
+ ~ThrowAssign() { ++dtor_called; }
+};
+int ThrowAssign::dtor_called = 0;
+
+template <class T, class Arg = T, bool Expect = true>
+void assert_assignable() {
+ static_assert(std::is_assignable<optional<T>&, Arg>::value == Expect, "");
+ static_assert(!std::is_assignable<const optional<T>&, Arg>::value, "");
+}
+
+struct MismatchType {
+ explicit MismatchType(int) {}
+ explicit MismatchType(char*) {}
+ explicit MismatchType(int*) = delete;
+ MismatchType& operator=(int) { return *this; }
+ MismatchType& operator=(int*) { return *this; }
+ MismatchType& operator=(char*) = delete;
+};
+
+struct FromOptionalType {
+ using Opt = std::optional<FromOptionalType>;
+ FromOptionalType() = default;
+ FromOptionalType(FromOptionalType const&) = delete;
+ template <class Dummy = void>
+ constexpr FromOptionalType(Opt&) { Dummy::BARK; }
+ template <class Dummy = void>
+ constexpr FromOptionalType& operator=(Opt&) { Dummy::BARK; return *this; }
+};
+
+void test_sfinae() {
+ using I = TestTypes::TestType;
+ using E = ExplicitTestTypes::TestType;
+ assert_assignable<int>();
+ assert_assignable<int, int&>();
+ assert_assignable<int, int const&>();
+ // Implicit test type
+ assert_assignable<I, I const&>();
+ assert_assignable<I, I&&>();
+ assert_assignable<I, int>();
+ assert_assignable<I, void*, false>();
+ // Explicit test type
+ assert_assignable<E, E const&>();
+ assert_assignable<E, E &&>();
+ assert_assignable<E, int>();
+ assert_assignable<E, void*, false>();
+ // Mismatch type
+ assert_assignable<MismatchType, int>();
+ assert_assignable<MismatchType, int*, false>();
+ assert_assignable<MismatchType, char*, false>();
+ // Type constructible from optional
+ assert_assignable<FromOptionalType, std::optional<FromOptionalType>&, false>();
+}
+
+void test_with_test_type()
+{
+ using T = TestTypes::TestType;
+ T::reset();
+ { // to empty
+ optional<T> opt;
+ opt = 3;
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(3));
+ }
+ { // to existing
+ optional<T> opt(42);
+ T::reset_constructors();
+ opt = 3;
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 1);
+ assert(T::value_assigned == 1);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(3));
+ }
+ { // test default argument
+ optional<T> opt;
+ T::reset_constructors();
+ opt = {1, 2};
+ assert(T::alive == 1);
+ assert(T::constructed == 2);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 1);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1, 2));
+ }
+ { // test default argument
+ optional<T> opt(42);
+ T::reset_constructors();
+ opt = {1, 2};
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::assigned == 1);
+ assert(T::move_assigned == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1, 2));
+ }
+ { // test default argument
+ optional<T> opt;
+ T::reset_constructors();
+ opt = {1};
+ assert(T::alive == 1);
+ assert(T::constructed == 2);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 1);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1));
+ }
+ { // test default argument
+ optional<T> opt(42);
+ T::reset_constructors();
+ opt = {};
+ assert(static_cast<bool>(opt) == false);
+ assert(T::alive == 0);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 1);
+ }
+}
+
+template <class T, class Value = int>
+void test_with_type() {
+ { // to empty
+ optional<T> opt;
+ opt = Value(3);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(3));
+ }
+ { // to existing
+ optional<T> opt(Value(42));
+ opt = Value(3);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(3));
+ }
+ { // test const
+ optional<T> opt(Value(42));
+ const T t(Value(3));
+ opt = t;
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(3));
+ }
+ { // test default argument
+ optional<T> opt;
+ opt = {Value(1)};
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1));
+ }
+ { // test default argument
+ optional<T> opt(Value(42));
+ opt = {};
+ assert(static_cast<bool>(opt) == false);
+ }
+}
+
+template <class T>
+void test_with_type_multi() {
+ test_with_type<T>();
+ { // test default argument
+ optional<T> opt;
+ opt = {1, 2};
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1, 2));
+ }
+ { // test default argument
+ optional<T> opt(42);
+ opt = {1, 2};
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1, 2));
+ }
+}
+
+void test_throws()
+{
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using T = ThrowAssign;
+ {
+ using T = ThrowAssign;
+ optional<T> opt;
+ try {
+ opt = 42;
+ assert(false);
+ } catch (int) {}
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(T::dtor_called == 0);
+ {
+ T::dtor_called = 0;
+ optional<T> opt(std::in_place);
+ try {
+ opt = 42;
+ assert(false);
+ } catch (int) {}
+ assert(static_cast<bool>(opt) == true);
+ assert(T::dtor_called == 0);
+ }
+ assert(T::dtor_called == 1);
+#endif
+}
+
+enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 };
+
+using Fn = void(*)();
+
+int main()
+{
+ test_sfinae();
+ // Test with instrumented type
+ test_with_test_type();
+ // Test with various scalar types
+ test_with_type<int>();
+ test_with_type<MyEnum, MyEnum>();
+ test_with_type<int, MyEnum>();
+ test_with_type<Fn, Fn>();
+ // Test types with multi argument constructors
+ test_with_type_multi<ConstexprTestTypes::TestType>();
+ test_with_type_multi<TrivialTestTypes::TestType>();
+ // Test move only types
+ {
+ optional<std::unique_ptr<int>> opt;
+ opt = std::unique_ptr<int>(new int(3));
+ assert(static_cast<bool>(opt) == true);
+ assert(**opt == 3);
+ }
+ {
+ optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new int(2)));
+ opt = std::unique_ptr<int>(new int(3));
+ assert(static_cast<bool>(opt) == true);
+ assert(**opt == 3);
+ }
+ test_throws();
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp
new file mode 100644
index 000000000000..d471c053c907
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp
@@ -0,0 +1,254 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// From LWG2451:
+// template<class U>
+// optional<T>& operator=(const optional<U>& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+struct X
+{
+ static bool throw_now;
+
+ X() = default;
+ X(int)
+ {
+ if (throw_now)
+ TEST_THROW(6);
+ }
+};
+
+bool X::throw_now = false;
+
+struct Y1
+{
+ Y1() = default;
+ Y1(const int&) {}
+ Y1& operator=(const Y1&) = delete;
+};
+
+struct Y2
+{
+ Y2() = default;
+ Y2(const int&) = delete;
+ Y2& operator=(const int&) { return *this; }
+};
+
+template <class T>
+struct AssignableFrom {
+ static int type_constructed;
+ static int type_assigned;
+static int int_constructed;
+ static int int_assigned;
+
+ static void reset() {
+ type_constructed = int_constructed = 0;
+ type_assigned = int_assigned = 0;
+ }
+
+ AssignableFrom() = default;
+
+ explicit AssignableFrom(T) { ++type_constructed; }
+ AssignableFrom& operator=(T) { ++type_assigned; return *this; }
+
+ AssignableFrom(int) { ++int_constructed; }
+ AssignableFrom& operator=(int) { ++int_assigned; return *this; }
+private:
+ AssignableFrom(AssignableFrom const&) = delete;
+ AssignableFrom& operator=(AssignableFrom const&) = delete;
+};
+
+template <class T> int AssignableFrom<T>::type_constructed = 0;
+template <class T> int AssignableFrom<T>::type_assigned = 0;
+template <class T> int AssignableFrom<T>::int_constructed = 0;
+template <class T> int AssignableFrom<T>::int_assigned = 0;
+
+
+void test_with_test_type() {
+ using T = TestTypes::TestType;
+ T::reset();
+ { // non-empty to empty
+ T::reset_constructors();
+ optional<T> opt;
+ const optional<int> other(42);
+ opt = other;
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == true);
+ assert(*other == 42);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(42));
+ }
+ assert(T::alive == 0);
+ { // non-empty to non-empty
+ optional<T> opt(101);
+ const optional<int> other(42);
+ T::reset_constructors();
+ opt = other;
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 1);
+ assert(T::value_assigned == 1);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == true);
+ assert(*other == 42);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(42));
+ }
+ assert(T::alive == 0);
+ { // empty to non-empty
+ optional<T> opt(101);
+ const optional<int> other;
+ T::reset_constructors();
+ opt = other;
+ assert(T::alive == 0);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(other) == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(T::alive == 0);
+ { // empty to empty
+ optional<T> opt;
+ const optional<int> other;
+ T::reset_constructors();
+ opt = other;
+ assert(T::alive == 0);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(T::alive == 0);
+}
+
+void test_ambigious_assign() {
+ using OptInt = std::optional<int>;
+ {
+ using T = AssignableFrom<OptInt const&>;
+ const OptInt a(42);
+ T::reset();
+ {
+ std::optional<T> t;
+ t = a;
+ assert(T::type_constructed == 1);
+ assert(T::type_assigned == 0);
+ assert(T::int_constructed == 0);
+ assert(T::int_assigned == 0);
+ }
+ T::reset();
+ {
+ std::optional<T> t(42);
+ t = a;
+ assert(T::type_constructed == 0);
+ assert(T::type_assigned == 1);
+ assert(T::int_constructed == 1);
+ assert(T::int_assigned == 0);
+ }
+ T::reset();
+ {
+ std::optional<T> t(42);
+ t = std::move(a);
+ assert(T::type_constructed == 0);
+ assert(T::type_assigned == 1);
+ assert(T::int_constructed == 1);
+ assert(T::int_assigned == 0);
+ }
+ }
+ {
+ using T = AssignableFrom<OptInt&>;
+ OptInt a(42);
+ T::reset();
+ {
+ std::optional<T> t;
+ t = a;
+ assert(T::type_constructed == 1);
+ assert(T::type_assigned == 0);
+ assert(T::int_constructed == 0);
+ assert(T::int_assigned == 0);
+ }
+ {
+ using Opt = std::optional<T>;
+ static_assert(!std::is_assignable_v<Opt&, OptInt const&>, "");
+ }
+ }
+}
+
+
+int main()
+{
+ test_with_test_type();
+ test_ambigious_assign();
+ {
+ optional<int> opt;
+ constexpr optional<short> opt2;
+ opt = opt2;
+ static_assert(static_cast<bool>(opt2) == false, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt;
+ constexpr optional<short> opt2(short{2});
+ opt = opt2;
+ static_assert(static_cast<bool>(opt2) == true, "");
+ static_assert(*opt2 == 2, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+ {
+ optional<int> opt(3);
+ constexpr optional<short> opt2;
+ opt = opt2;
+ static_assert(static_cast<bool>(opt2) == false, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt(3);
+ constexpr optional<short> opt2(short{2});
+ opt = opt2;
+ static_assert(static_cast<bool>(opt2) == true, "");
+ static_assert(*opt2 == 2, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<X> opt;
+ optional<int> opt2(42);
+ assert(static_cast<bool>(opt2) == true);
+ try
+ {
+ X::throw_now = true;
+ opt = opt2;
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ }
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..98c90aa1d4fb
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// optional<T>& operator=(const optional<T>& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+struct X
+{
+ static bool throw_now;
+
+ X() = default;
+ X(const X&)
+ {
+ if (throw_now)
+ TEST_THROW(6);
+ }
+};
+
+bool X::throw_now = false;
+
+template <class Tp>
+constexpr bool assign_empty(optional<Tp>&& lhs) {
+ const optional<Tp> rhs;
+ lhs = rhs;
+ return !lhs.has_value() && !rhs.has_value();
+}
+
+template <class Tp>
+constexpr bool assign_value(optional<Tp>&& lhs) {
+ const optional<Tp> rhs(101);
+ lhs = rhs;
+ return lhs.has_value() && rhs.has_value() && *lhs == *rhs;
+}
+
+int main()
+{
+ {
+ using O = optional<int>;
+ LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
+ LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+ assert(assign_empty(O{42}));
+ assert(assign_value(O{42}));
+ }
+ {
+ using O = optional<TrivialTestTypes::TestType>;
+ LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
+ LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
+ assert(assign_empty(O{42}));
+ assert(assign_value(O{42}));
+ }
+ {
+ using O = optional<TestTypes::TestType>;
+ assert(assign_empty(O{42}));
+ assert(assign_value(O{42}));
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> opt(3);
+ const optional<T> opt2;
+ assert(T::alive == 1);
+ opt = opt2;
+ assert(T::alive == 0);
+ assert(!opt2.has_value());
+ assert(!opt.has_value());
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<X> opt;
+ optional<X> opt2(X{});
+ assert(static_cast<bool>(opt2) == true);
+ try
+ {
+ X::throw_now = true;
+ opt = opt2;
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
new file mode 100644
index 000000000000..b5362589963c
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp
@@ -0,0 +1,237 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class... Args> void optional<T>::emplace(Args&&... args);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+#include <memory>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+class X
+{
+ int i_;
+ int j_ = 0;
+public:
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
+
+ friend bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Y
+{
+public:
+ static bool dtor_called;
+ Y() = default;
+ Y(int) { TEST_THROW(6);}
+ ~Y() {dtor_called = true;}
+};
+
+bool Y::dtor_called = false;
+
+template <class T>
+void test_one_arg() {
+ using Opt = std::optional<T>;
+ {
+ Opt opt;
+ opt.emplace();
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(0));
+ }
+ {
+ Opt opt;
+ opt.emplace(1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1));
+ }
+ {
+ Opt opt(2);
+ opt.emplace();
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(0));
+ }
+ {
+ Opt opt(2);
+ opt.emplace(1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(1));
+ }
+}
+
+
+template <class T>
+void test_multi_arg()
+{
+ test_one_arg<T>();
+ using Opt = std::optional<T>;
+ {
+ Opt opt;
+ opt.emplace(101, 41);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(101, 41));
+ }
+ {
+ Opt opt;
+ opt.emplace({1, 2, 3, 4});
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(4)); // T sets its value to the size of the init list
+ }
+ {
+ Opt opt;
+ opt.emplace({1, 2, 3, 4, 5}, 6);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(5)); // T sets its value to the size of the init list
+ }
+}
+
+template <class T>
+void test_on_test_type() {
+
+ T::reset();
+ optional<T> opt;
+ assert(T::alive == 0);
+ {
+ T::reset_constructors();
+ opt.emplace();
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::default_constructed == 1);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T());
+ }
+ {
+ T::reset_constructors();
+ opt.emplace();
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::default_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T());
+ }
+ {
+ T::reset_constructors();
+ opt.emplace(101);
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(101));
+ }
+ {
+ T::reset_constructors();
+ opt.emplace(-10, 99);
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(-10, 99));
+ }
+ {
+ T::reset_constructors();
+ opt.emplace(-10, 99);
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(-10, 99));
+ }
+ {
+ T::reset_constructors();
+ opt.emplace({-10, 99, 42, 1});
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(4)); // size of the initializer list
+ }
+ {
+ T::reset_constructors();
+ opt.emplace({-10, 99, 42, 1}, 42);
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(4)); // size of the initializer list
+ }
+}
+
+
+
+int main()
+{
+ {
+ test_on_test_type<TestTypes::TestType>();
+ test_on_test_type<ExplicitTestTypes::TestType>();
+ }
+ {
+ using T = int;
+ test_one_arg<T>();
+ test_one_arg<const T>();
+ }
+ {
+ using T = ConstexprTestTypes::TestType;
+ test_multi_arg<T>();
+ }
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ test_multi_arg<T>();
+ }
+ {
+ using T = TrivialTestTypes::TestType;
+ test_multi_arg<T>();
+ }
+ {
+ using T = ExplicitTrivialTestTypes::TestType;
+ test_multi_arg<T>();
+ }
+ {
+ optional<const int> opt;
+ opt.emplace(42);
+ assert(*opt == 42);
+ opt.emplace();
+ assert(*opt == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ Y::dtor_called = false;
+ {
+ Y y;
+ optional<Y> opt(y);
+ try
+ {
+ assert(static_cast<bool>(opt) == true);
+ assert(Y::dtor_called == false);
+ opt.emplace(1);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ assert(Y::dtor_called == true);
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp
new file mode 100644
index 000000000000..1c3c69a70303
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class U, class... Args>
+// void optional<T>::emplace(initializer_list<U> il, Args&&... args);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+#include <vector>
+
+#include "test_macros.h"
+
+using std::optional;
+
+class X
+{
+ int i_;
+ int j_ = 0;
+public:
+ static bool dtor_called;
+ constexpr X() : i_(0) {}
+ constexpr X(int i) : i_(i) {}
+ constexpr X(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
+ ~X() {dtor_called = true;}
+
+ friend constexpr bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+bool X::dtor_called = false;
+
+class Y
+{
+ int i_;
+ int j_ = 0;
+public:
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
+
+ friend constexpr bool operator==(const Y& x, const Y& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Z
+{
+ int i_;
+ int j_ = 0;
+public:
+ static bool dtor_called;
+ Z() : i_(0) {}
+ Z(int i) : i_(i) {}
+ Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
+ { TEST_THROW(6);}
+ ~Z() {dtor_called = true;}
+
+ friend bool operator==(const Z& x, const Z& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+bool Z::dtor_called = false;
+
+int main()
+{
+ {
+ X x;
+ optional<X> opt(x);
+ assert(X::dtor_called == false);
+ opt.emplace({1, 2});
+ assert(X::dtor_called == true);
+ assert(*opt == X({1, 2}));
+ }
+ {
+ optional<std::vector<int>> opt;
+ opt.emplace({1, 2, 3}, std::allocator<int>());
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == std::vector<int>({1, 2, 3}));
+ }
+ {
+ optional<Y> opt;
+ opt.emplace({1, 2});
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == Y({1, 2}));
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ Z z;
+ optional<Z> opt(z);
+ try
+ {
+ assert(static_cast<bool>(opt) == true);
+ assert(Z::dtor_called == false);
+ opt.emplace({1, 2});
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ assert(Z::dtor_called == true);
+ }
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..3ba261b52464
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// optional<T>& operator=(optional<T>&& rhs)
+// noexcept(is_nothrow_move_assignable<T>::value &&
+// is_nothrow_move_constructible<T>::value);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+struct X
+{
+ static bool throw_now;
+ static int alive;
+
+ X() { ++alive; }
+ X(X&&)
+ {
+ if (throw_now)
+ TEST_THROW(6);
+ ++alive;
+ }
+
+ X& operator=(X&&)
+ {
+ if (throw_now)
+ TEST_THROW(42);
+ return *this;
+ }
+
+ ~X() { assert(alive > 0); --alive; }
+};
+
+struct Y {};
+
+bool X::throw_now = false;
+int X::alive = 0;
+
+int main()
+{
+ {
+ static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
+ optional<int> opt;
+ constexpr optional<int> opt2;
+ opt = std::move(opt2);
+ static_assert(static_cast<bool>(opt2) == false, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt;
+ constexpr optional<int> opt2(2);
+ opt = std::move(opt2);
+ static_assert(static_cast<bool>(opt2) == true, "");
+ static_assert(*opt2 == 2, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+ {
+ optional<int> opt(3);
+ constexpr optional<int> opt2;
+ opt = std::move(opt2);
+ static_assert(static_cast<bool>(opt2) == false, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> opt(3);
+ optional<T> opt2;
+ assert(T::alive == 1);
+ opt = std::move(opt2);
+ assert(T::alive == 0);
+ assert(static_cast<bool>(opt2) == false);
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt(3);
+ constexpr optional<int> opt2(2);
+ opt = std::move(opt2);
+ static_assert(static_cast<bool>(opt2) == true, "");
+ static_assert(*opt2 == 2, "");
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
+ X::alive = 0;
+ X::throw_now = false;
+ optional<X> opt;
+ optional<X> opt2(X{});
+ assert(X::alive == 1);
+ assert(static_cast<bool>(opt2) == true);
+ try
+ {
+ X::throw_now = true;
+ opt = std::move(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(X::alive == 1);
+ }
+ assert(X::alive == 0);
+ {
+ static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
+ X::throw_now = false;
+ optional<X> opt(X{});
+ optional<X> opt2(X{});
+ assert(X::alive == 2);
+ assert(static_cast<bool>(opt2) == true);
+ try
+ {
+ X::throw_now = true;
+ opt = std::move(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 42);
+ assert(static_cast<bool>(opt) == true);
+ }
+ assert(X::alive == 2);
+ }
+ assert(X::alive == 0);
+#endif // TEST_HAS_NO_EXCEPTIONS
+ {
+ static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
+ }
+ {
+ struct ThrowsMove {
+ ThrowsMove() noexcept {}
+ ThrowsMove(ThrowsMove const&) noexcept {}
+ ThrowsMove(ThrowsMove &&) noexcept(false) {}
+ ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
+ ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
+ };
+ static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
+ struct ThrowsMoveAssign {
+ ThrowsMoveAssign() noexcept {}
+ ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
+ ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
+ ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
+ ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
+ };
+ static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
+ struct NoThrowMove {
+ NoThrowMove() noexcept(false) {}
+ NoThrowMove(NoThrowMove const&) noexcept(false) {}
+ NoThrowMove(NoThrowMove &&) noexcept {}
+ NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
+ NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
+ };
+ static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp
new file mode 100644
index 000000000000..991f4334304c
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.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
+// <optional>
+
+// optional<T>& operator=(nullopt_t) noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+using std::nullopt_t;
+using std::nullopt;
+
+int main()
+{
+ {
+ optional<int> opt;
+ static_assert(noexcept(opt = nullopt) == true, "");
+ opt = nullopt;
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ optional<int> opt(3);
+ opt = nullopt;
+ assert(static_cast<bool>(opt) == false);
+ }
+ using TT = TestTypes::TestType;
+ TT::reset();
+ {
+ optional<TT> opt;
+ static_assert(noexcept(opt = nullopt) == true, "");
+ assert(TT::destroyed == 0);
+ opt = nullopt;
+ assert(TT::constructed == 0);
+ assert(TT::alive == 0);
+ assert(TT::destroyed == 0);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(TT::alive == 0);
+ assert(TT::destroyed == 0);
+ TT::reset();
+ {
+ optional<TT> opt(42);
+ assert(TT::destroyed == 0);
+ TT::reset_constructors();
+ opt = nullopt;
+ assert(TT::constructed == 0);
+ assert(TT::alive == 0);
+ assert(TT::destroyed == 1);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(TT::alive == 0);
+ assert(TT::destroyed == 1);
+ TT::reset();
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp
new file mode 100644
index 000000000000..db7fc19bfb10
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp
@@ -0,0 +1,268 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// From LWG2451:
+// template <class U>
+// optional<T>& operator=(optional<U>&& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+struct X
+{
+ static bool throw_now;
+
+ X() = default;
+ X(int &&)
+ {
+ if (throw_now)
+ TEST_THROW(6);
+ }
+};
+
+bool X::throw_now = false;
+
+struct Y1
+{
+ Y1() = default;
+ Y1(const int&) {}
+ Y1& operator=(const Y1&) = delete;
+};
+
+struct Y2
+{
+ Y2() = default;
+ Y2(const int&) = delete;
+ Y2& operator=(const int&) { return *this; }
+};
+
+class B {};
+class D : public B {};
+
+
+template <class T>
+struct AssignableFrom {
+ static int type_constructed;
+ static int type_assigned;
+static int int_constructed;
+ static int int_assigned;
+
+ static void reset() {
+ type_constructed = int_constructed = 0;
+ type_assigned = int_assigned = 0;
+ }
+
+ AssignableFrom() = default;
+
+ explicit AssignableFrom(T) { ++type_constructed; }
+ AssignableFrom& operator=(T) { ++type_assigned; return *this; }
+
+ AssignableFrom(int) { ++int_constructed; }
+ AssignableFrom& operator=(int) { ++int_assigned; return *this; }
+private:
+ AssignableFrom(AssignableFrom const&) = delete;
+ AssignableFrom& operator=(AssignableFrom const&) = delete;
+};
+
+template <class T> int AssignableFrom<T>::type_constructed = 0;
+template <class T> int AssignableFrom<T>::type_assigned = 0;
+template <class T> int AssignableFrom<T>::int_constructed = 0;
+template <class T> int AssignableFrom<T>::int_assigned = 0;
+
+void test_with_test_type() {
+ using T = TestTypes::TestType;
+ T::reset();
+ { // non-empty to empty
+ T::reset_constructors();
+ optional<T> opt;
+ optional<int> other(42);
+ opt = std::move(other);
+ assert(T::alive == 1);
+ assert(T::constructed == 1);
+ assert(T::value_constructed == 1);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == true);
+ assert(*other == 42);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(42));
+ }
+ assert(T::alive == 0);
+ { // non-empty to non-empty
+ optional<T> opt(101);
+ optional<int> other(42);
+ T::reset_constructors();
+ opt = std::move(other);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 1);
+ assert(T::value_assigned == 1);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == true);
+ assert(*other == 42);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == T(42));
+ }
+ assert(T::alive == 0);
+ { // empty to non-empty
+ optional<T> opt(101);
+ optional<int> other;
+ T::reset_constructors();
+ opt = std::move(other);
+ assert(T::alive == 0);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 1);
+ assert(static_cast<bool>(other) == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(T::alive == 0);
+ { // empty to empty
+ optional<T> opt;
+ optional<int> other;
+ T::reset_constructors();
+ opt = std::move(other);
+ assert(T::alive == 0);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ assert(static_cast<bool>(other) == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(T::alive == 0);
+}
+
+
+void test_ambigious_assign() {
+ using OptInt = std::optional<int>;
+ {
+ using T = AssignableFrom<OptInt&&>;
+ T::reset();
+ {
+ OptInt a(42);
+ std::optional<T> t;
+ t = std::move(a);
+ assert(T::type_constructed == 1);
+ assert(T::type_assigned == 0);
+ assert(T::int_constructed == 0);
+ assert(T::int_assigned == 0);
+ }
+ {
+ using Opt = std::optional<T>;
+ static_assert(!std::is_assignable<Opt&, const OptInt&&>::value, "");
+ static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
+ static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
+ }
+ }
+ {
+ using T = AssignableFrom<OptInt const&&>;
+ T::reset();
+ {
+ const OptInt a(42);
+ std::optional<T> t;
+ t = std::move(a);
+ assert(T::type_constructed == 1);
+ assert(T::type_assigned == 0);
+ assert(T::int_constructed == 0);
+ assert(T::int_assigned == 0);
+ }
+ T::reset();
+ {
+ OptInt a(42);
+ std::optional<T> t;
+ t = std::move(a);
+ assert(T::type_constructed == 1);
+ assert(T::type_assigned == 0);
+ assert(T::int_constructed == 0);
+ assert(T::int_assigned == 0);
+ }
+ {
+ using Opt = std::optional<T>;
+ static_assert(std::is_assignable<Opt&, OptInt&&>::value, "");
+ static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
+ static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
+ }
+ }
+}
+
+
+int main()
+{
+ test_with_test_type();
+ test_ambigious_assign();
+ {
+ optional<int> opt;
+ optional<short> opt2;
+ opt = std::move(opt2);
+ assert(static_cast<bool>(opt2) == false);
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt;
+ optional<short> opt2(short{2});
+ opt = std::move(opt2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+ {
+ optional<int> opt(3);
+ optional<short> opt2;
+ opt = std::move(opt2);
+ assert(static_cast<bool>(opt2) == false);
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ }
+ {
+ optional<int> opt(3);
+ optional<short> opt2(short{2});
+ opt = std::move(opt2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
+ assert(*opt == *opt2);
+ }
+ {
+ optional<std::unique_ptr<B>> opt;
+ optional<std::unique_ptr<D>> other(new D());
+ opt = std::move(other);
+ assert(static_cast<bool>(opt) == true);
+ assert(static_cast<bool>(other) == true);
+ assert(opt->get() != nullptr);
+ assert(other->get() == nullptr);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<X> opt;
+ optional<int> opt2(42);
+ assert(static_cast<bool>(opt2) == true);
+ try
+ {
+ X::throw_now = true;
+ opt = std::move(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ assert(static_cast<bool>(opt) == false);
+ }
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..c4d4763a6f0a
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class U>
+// constexpr EXPLICIT optional(U&& u);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+
+
+using std::optional;
+
+struct ImplicitThrow
+{
+ constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+};
+
+struct ExplicitThrow
+{
+ constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+};
+
+
+template <class To, class From>
+constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
+{
+ using O = optional<To>;
+ static_assert(test_convertible<O, From>(), "");
+ static_assert(!test_convertible<O, void*>(), "");
+ static_assert(!test_convertible<O, From, int>(), "");
+ return opt && *opt == static_cast<To>(v);
+}
+
+template <class To, class Input, class Expect>
+constexpr bool explicit_conversion(Input&& in, const Expect& v)
+{
+ using O = optional<To>;
+ static_assert(std::is_constructible<O, Input>::value, "");
+ static_assert(!std::is_convertible<Input, O>::value, "");
+ static_assert(!std::is_constructible<O, void*>::value, "");
+ static_assert(!std::is_constructible<O, Input, int>::value, "");
+ optional<To> opt(std::forward<Input>(in));
+ return opt && *opt == static_cast<To>(v);
+}
+
+void test_implicit()
+{
+ {
+ using T = long long;
+ static_assert(implicit_conversion<long long>(42, 42), "");
+ }
+ {
+ using T = long double;
+ static_assert(implicit_conversion<long double>(3.14, 3.14), "");
+ }
+ {
+ int x = 42;
+ optional<void* const> o(&x);
+ assert(*o == &x);
+ }
+ {
+ using T = TrivialTestTypes::TestType;
+ static_assert(implicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = TestTypes::TestType;
+ assert(implicit_conversion<T>(3, T(3)));
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ try {
+ using T = ImplicitThrow;
+ optional<T> t = 42;
+ assert(false);
+ ((void)t);
+ } catch (int) {
+ }
+ }
+#endif
+}
+
+void test_explicit() {
+ {
+ using T = ExplicitTrivialTestTypes::TestType;
+ using O = optional<T>;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ using O = optional<T>;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ static_assert(!std::is_convertible<int, T>::value, "");
+ }
+ {
+ using T = ExplicitTestTypes::TestType;
+ using O = optional<T>;
+ T::reset();
+ {
+ assert(explicit_conversion<T>(42, 42));
+ assert(T::alive == 0);
+ }
+ T::reset();
+ {
+ optional<T> t(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ assert(T::copy_constructed == 0);
+ assert(t.value().value == 42);
+ }
+ assert(T::alive == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ try {
+ using T = ExplicitThrow;
+ optional<T> t(42);
+ assert(false);
+ } catch (int) {
+ }
+ }
+#endif
+}
+
+int main() {
+ test_implicit();
+ test_explicit();
+}
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
new file mode 100644
index 000000000000..34a12b8ad1c3
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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 T& v);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+int main()
+{
+ {
+ typedef int T;
+ constexpr T t(5);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+
+ }
+ {
+ typedef double T;
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+
+ }
+ {
+ const int x = 42;
+ optional<const int> o(x);
+ assert(*o == x);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ const T t(3);
+ optional<T> opt = t;
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
+ T::reset();
+ const T t(3);
+ optional<T> opt(t);
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr T t(3);
+ constexpr optional<T> opt = {t};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ struct Z {
+ Z(int) {}
+ Z(const Z&) {throw 6;}
+ };
+ typedef Z T;
+ try
+ {
+ const T t(3);
+ optional<T> opt(t);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
new file mode 100644
index 000000000000..e12f6cb28f5a
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
@@ -0,0 +1,134 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class U>
+// optional(const optional<U>& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+template <class T, class U>
+void
+test(const optional<U>& rhs, bool is_going_to_throw = false)
+{
+ bool rhs_engaged = static_cast<bool>(rhs);
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ optional<T> lhs = rhs;
+ assert(is_going_to_throw == false);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw) return;
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
+#endif
+}
+
+class X
+{
+ int i_;
+public:
+ X(int i) : i_(i) {}
+ X(const X& x) : i_(x.i_) {}
+ ~X() {i_ = 0;}
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+class Y
+{
+ int i_;
+public:
+ Y(int i) : i_(i) {}
+
+ friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+};
+
+int count = 0;
+
+class Z
+{
+ int i_;
+public:
+ Z(int i) : i_(i) {TEST_THROW(6);}
+
+ friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+};
+
+
+int main()
+{
+ {
+ typedef short U;
+ typedef int T;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef short U;
+ typedef int T;
+ optional<U> rhs(U{3});
+ test<T>(rhs);
+ }
+ {
+ typedef X T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef X T;
+ typedef int U;
+ optional<U> rhs(U{3});
+ test<T>(rhs);
+ }
+ {
+ typedef Y T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Y T;
+ typedef int U;
+ optional<U> rhs(U{3});
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(U{3});
+ test<T>(rhs, true);
+ }
+
+ static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), "");
+}
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
new file mode 100644
index 000000000000..5906d4edd119
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// optional(const optional<T>& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+template <class T, class ...InitArgs>
+void test(InitArgs&&... args)
+{
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
+}
+
+void test_throwing_ctor() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ struct Z {
+ Z() : count(0) {}
+ Z(Z const& o) : count(o.count + 1)
+ { if (count == 2) throw 6; }
+ int count;
+ };
+ const Z z;
+ const optional<Z> rhs(z);
+ try
+ {
+ optional<Z> lhs(rhs);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#endif
+}
+
+template <class T, class ...InitArgs>
+void test_ref(InitArgs&&... args)
+{
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
+}
+
+
+void test_reference_extension()
+{
+#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
+ using T = TestTypes::TestType;
+ T::reset();
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&>();
+ test_ref<T&>(t);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::destroyed == 1);
+ assert(T::alive == 0);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&>();
+ test_ref<T const&>(t);
+ test_ref<T const&>(ct);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
+ static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
+ }
+#endif
+}
+
+int main()
+{
+ test<int>();
+ test<int>(3);
+ {
+ const optional<const int> o(42);
+ optional<const int> o2(o);
+ assert(*o2 == 42);
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs;
+ assert(T::alive == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value() == false);
+ assert(T::alive == 0);
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value());
+ assert(T::copy_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ test_reference_extension();
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
new file mode 100644
index 000000000000..62795b91f9fd
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/default.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
+// <optional>
+
+// constexpr optional() noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+template <class Opt>
+void
+test_constexpr()
+{
+ static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+
+ constexpr Opt opt;
+ static_assert(static_cast<bool>(opt) == false, "");
+
+ struct test_constexpr_ctor
+ : public Opt
+ {
+ constexpr test_constexpr_ctor() {}
+ };
+}
+
+template <class Opt>
+void
+test()
+{
+ static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ {
+ Opt opt;
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ const Opt opt;
+ assert(static_cast<bool>(opt) == false);
+ }
+
+ struct test_constexpr_ctor
+ : public Opt
+ {
+ constexpr test_constexpr_ctor() {}
+ };
+}
+
+int main()
+{
+ test_constexpr<optional<int>>();
+ test_constexpr<optional<int*>>();
+ test_constexpr<optional<ImplicitTypes::NoCtors>>();
+ test_constexpr<optional<NonTrivialTypes::NoCtors>>();
+ test_constexpr<optional<NonConstexprTypes::NoCtors>>();
+ test<optional<NonLiteralTypes::NoCtors>>();
+ // EXTENSIONS
+#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
+ test_constexpr<optional<int&>>();
+ test_constexpr<optional<const int&>>();
+ test_constexpr<optional<int&>>();
+ test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
+ test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
new file mode 100644
index 000000000000..64ac05316c2a
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class U>
+// explicit optional(const optional<U>& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+template <class T, class U>
+void
+test(const optional<U>& rhs, bool is_going_to_throw = false)
+{
+ static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), "");
+ bool rhs_engaged = static_cast<bool>(rhs);
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ optional<T> lhs(rhs);
+ assert(is_going_to_throw == false);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == T(*rhs));
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw) return;
+ optional<T> lhs(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == T(*rhs));
+#endif
+}
+
+class X
+{
+ int i_;
+public:
+ explicit X(int i) : i_(i) {}
+ X(const X& x) : i_(x.i_) {}
+ ~X() {i_ = 0;}
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+class Y
+{
+ int i_;
+public:
+ explicit Y(int i) : i_(i) {}
+
+ friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+};
+
+int count = 0;
+
+class Z
+{
+ int i_;
+public:
+ explicit Z(int i) : i_(i) { TEST_THROW(6);}
+
+ friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+};
+
+
+int main()
+{
+ {
+ typedef X T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef X T;
+ typedef int U;
+ optional<U> rhs(3);
+ test<T>(rhs);
+ }
+ {
+ typedef Y T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Y T;
+ typedef int U;
+ optional<U> rhs(3);
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(3);
+ test<T>(rhs, true);
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
new file mode 100644
index 000000000000..2c6757a95825
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class U>
+// explicit optional(optional<U>&& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+template <class T, class U>
+void
+test(optional<U>&& rhs, bool is_going_to_throw = false)
+{
+ static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), "");
+ bool rhs_engaged = static_cast<bool>(rhs);
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ optional<T> lhs(std::move(rhs));
+ assert(is_going_to_throw == false);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw) return;
+ optional<T> lhs(std::move(rhs));
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+#endif
+}
+
+class X
+{
+ int i_;
+public:
+ explicit X(int i) : i_(i) {}
+ X(X&& x) : i_(std::exchange(x.i_, 0)) {}
+ ~X() {i_ = 0;}
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+int count = 0;
+
+class Z
+{
+public:
+ explicit Z(int) { TEST_THROW(6); }
+};
+
+int main()
+{
+ {
+ optional<int> rhs;
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
new file mode 100644
index 000000000000..d0823d2c8c82
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <optional>
+
+// template <class... Args>
+// constexpr explicit optional(in_place_t, Args&&... args);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::in_place_t;
+using std::in_place;
+
+class X
+{
+ int i_;
+ int j_ = 0;
+public:
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
+
+ ~X() {}
+
+ friend bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Y
+{
+ int i_;
+ int j_ = 0;
+public:
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(int i, int j) : i_(i), j_(j) {}
+
+ friend constexpr bool operator==(const Y& x, const Y& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Z
+{
+public:
+ Z(int) {TEST_THROW(6);}
+};
+
+
+int main()
+{
+ {
+ constexpr optional<int> opt(in_place, 5);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor
+ : public optional<int>
+ {
+ constexpr test_constexpr_ctor(in_place_t, int i)
+ : optional<int>(in_place, i) {}
+ };
+
+ }
+ {
+ optional<const int> opt(in_place, 5);
+ assert(*opt == 5);
+ }
+ {
+ const optional<X> opt(in_place);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X());
+ }
+ {
+ const optional<X> opt(in_place, 5);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X(5));
+ }
+ {
+ const optional<X> opt(in_place, 5, 4);
+ assert(static_cast<bool>(opt) == true);
+ assert(*opt == X(5, 4));
+ }
+ {
+ constexpr optional<Y> opt(in_place);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(), "");
+
+ struct test_constexpr_ctor
+ : public optional<Y>
+ {
+ constexpr test_constexpr_ctor(in_place_t)
+ : optional<Y>(in_place) {}
+ };
+
+ }
+ {
+ constexpr optional<Y> opt(in_place, 5);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(5), "");
+
+ struct test_constexpr_ctor
+ : public optional<Y>
+ {
+ constexpr test_constexpr_ctor(in_place_t, int i)
+ : optional<Y>(in_place, i) {}
+ };
+
+ }
+ {
+ constexpr optional<Y> opt(in_place, 5, 4);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y(5, 4), "");
+
+ struct test_constexpr_ctor
+ : public optional<Y>
+ {
+ constexpr test_constexpr_ctor(in_place_t, int i, int j)
+ : optional<Y>(in_place, i, j) {}
+ };
+
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ try
+ {
+ const optional<Z> opt(in_place, 1);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
new file mode 100644
index 000000000000..6d9f45a97d45
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class U, class... Args>
+// constexpr
+// explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
+
+#include <optional>
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::in_place_t;
+using std::in_place;
+
+class X
+{
+ int i_;
+ int j_ = 0;
+public:
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
+
+ ~X() {}
+
+ friend bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Y
+{
+ int i_;
+ int j_ = 0;
+public:
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
+
+ friend constexpr bool operator==(const Y& x, const Y& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+class Z
+{
+ int i_;
+ int j_ = 0;
+public:
+ Z() : i_(0) {}
+ Z(int i) : i_(i) {}
+ Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
+ {TEST_THROW(6);}
+
+ friend bool operator==(const Z& x, const Z& y)
+ {return x.i_ == y.i_ && x.j_ == y.j_;}
+};
+
+int main()
+{
+ {
+ static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
+ static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1});
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
+ constexpr optional<Y> opt(in_place, {3, 1});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y{3, 1}, "");
+
+ struct test_constexpr_ctor
+ : public optional<Y>
+ {
+ constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i)
+ : optional<Y>(in_place, i) {}
+ };
+
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
+ try
+ {
+ optional<Z> opt(in_place, {3, 1});
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..bff6f5bf8f6f
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -0,0 +1,201 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// optional(optional<T>&& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+template <class T, class ...InitArgs>
+void test(InitArgs&&... args)
+{
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *orig);
+}
+
+void test_throwing_ctor() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ struct Z {
+ Z() : count(0) {}
+ Z(Z&& o) : count(o.count + 1)
+ { if (count == 2) throw 6; }
+ int count;
+ };
+ Z z;
+ optional<Z> rhs(std::move(z));
+ try
+ {
+ optional<Z> lhs(std::move(rhs));
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#endif
+}
+
+
+template <class T, class ...InitArgs>
+void test_ref(InitArgs&&... args)
+{
+ optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
+}
+
+void test_reference_extension()
+{
+#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
+ using T = TestTypes::TestType;
+ T::reset();
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&>();
+ test_ref<T&>(t);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::destroyed == 1);
+ assert(T::alive == 0);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&>();
+ test_ref<T const&>(t);
+ test_ref<T const&>(ct);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&&>();
+ test_ref<T&&>(std::move(t));
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&&>();
+ test_ref<T const&&>(std::move(t));
+ test_ref<T const&&>(std::move(ct));
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
+ static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
+ }
+#endif
+}
+
+
+int main()
+{
+ test<int>();
+ test<int>(3);
+ {
+ optional<const int> o(42);
+ optional<const int> o2(std::move(o));
+ assert(*o2 == 42);
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> rhs;
+ assert(T::alive == 0);
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value() == false);
+ assert(rhs.has_value() == false);
+ assert(T::alive == 0);
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value());
+ assert(rhs.has_value());
+ assert(lhs.value().value == 42);
+ assert(rhs.value().value == -1);
+ assert(T::move_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ struct ThrowsMove {
+ ThrowsMove() noexcept(false) {}
+ ThrowsMove(ThrowsMove const&) noexcept(false) {}
+ ThrowsMove(ThrowsMove &&) noexcept(false) {}
+ };
+ static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
+ struct NoThrowMove {
+ NoThrowMove() noexcept(false) {}
+ NoThrowMove(NoThrowMove const&) noexcept(false) {}
+ NoThrowMove(NoThrowMove &&) noexcept(true) {}
+ };
+ static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
+ }
+ {
+ test_reference_extension();
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
new file mode 100644
index 000000000000..468a00346fc7
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.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
+// <optional>
+
+// constexpr optional(nullopt_t) noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "archetypes.hpp"
+
+using std::optional;
+using std::nullopt_t;
+using std::nullopt;
+
+template <class Opt>
+void
+test_constexpr()
+{
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(std::is_trivially_destructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+
+ constexpr Opt opt(nullopt);
+ static_assert(static_cast<bool>(opt) == false, "");
+
+ struct test_constexpr_ctor
+ : public Opt
+ {
+ constexpr test_constexpr_ctor() {}
+ };
+}
+
+template <class Opt>
+void
+test()
+{
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(!std::is_trivially_destructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ {
+ Opt opt(nullopt);
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ const Opt opt(nullopt);
+ assert(static_cast<bool>(opt) == false);
+ }
+ struct test_constexpr_ctor
+ : public Opt
+ {
+ constexpr test_constexpr_ctor() {}
+ };
+}
+
+int main()
+{
+ test_constexpr<optional<int>>();
+ test_constexpr<optional<int*>>();
+ test_constexpr<optional<ImplicitTypes::NoCtors>>();
+ test_constexpr<optional<NonTrivialTypes::NoCtors>>();
+ test_constexpr<optional<NonConstexprTypes::NoCtors>>();
+ test<optional<NonLiteralTypes::NoCtors>>();
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
new file mode 100644
index 000000000000..0e180c14ec67
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class U>
+// optional(optional<U>&& rhs);
+
+#include <optional>
+#include <type_traits>
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+template <class T, class U>
+void
+test(optional<U>&& rhs, bool is_going_to_throw = false)
+{
+ bool rhs_engaged = static_cast<bool>(rhs);
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try
+ {
+ optional<T> lhs = std::move(rhs);
+ assert(is_going_to_throw == false);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw) return;
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+#endif
+}
+
+class X
+{
+ int i_;
+public:
+ X(int i) : i_(i) {}
+ X(X&& x) : i_(std::exchange(x.i_, 0)) {}
+ ~X() {i_ = 0;}
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+int count = 0;
+
+struct Z
+{
+ Z(int) { TEST_THROW(6); }
+};
+
+int main()
+{
+ {
+ optional<short> rhs;
+ test<int>(std::move(rhs));
+ }
+ {
+ optional<short> rhs(short{3});
+ test<int>(std::move(rhs));
+ }
+ {
+ optional<int> rhs;
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
+
+ static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
+}
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
new file mode 100644
index 000000000000..eee749d01707
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <optional>
+
+// constexpr optional(T&& v);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+
+using std::optional;
+
+
+class Z
+{
+public:
+ Z(int) {}
+ Z(Z&&) {TEST_THROW(6);}
+};
+
+
+int main()
+{
+ {
+ typedef int T;
+ constexpr optional<T> opt(T(5));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ typedef double T;
+ constexpr optional<T> opt(T(3));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ const int x = 42;
+ optional<const int> o(std::move(x));
+ assert(*o == 42);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = T{3};
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ T::reset();
+ optional<T> opt(T{3});
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = {3};
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ assert(T::move_constructed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {T(3)};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {3};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ constexpr optional<T> opt(T{3});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor
+ : public optional<T>
+ {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ struct Z {
+ Z(int) {}
+ Z(Z&&) {throw 6;}
+ };
+ typedef Z T;
+ try
+ {
+ T t(3);
+ optional<T> opt(std::move(t));
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp
new file mode 100644
index 000000000000..5132c9a73d0f
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// ~optional();
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct PODType {
+ int value;
+ int value2;
+};
+
+class X
+{
+public:
+ static bool dtor_called;
+ X() = default;
+ ~X() {dtor_called = true;}
+};
+
+bool X::dtor_called = false;
+
+int main()
+{
+ {
+ typedef int T;
+ static_assert(std::is_trivially_destructible<T>::value, "");
+ static_assert(std::is_trivially_destructible<optional<T>>::value, "");
+ static_assert(std::is_literal_type<optional<T>>::value, "");
+ }
+ {
+ typedef double T;
+ static_assert(std::is_trivially_destructible<T>::value, "");
+ static_assert(std::is_trivially_destructible<optional<T>>::value, "");
+ static_assert(std::is_literal_type<optional<T>>::value, "");
+ }
+ {
+ typedef PODType T;
+ static_assert(std::is_trivially_destructible<T>::value, "");
+ static_assert(std::is_trivially_destructible<optional<T>>::value, "");
+ static_assert(std::is_literal_type<optional<T>>::value, "");
+ }
+ {
+ typedef X T;
+ static_assert(!std::is_trivially_destructible<T>::value, "");
+ static_assert(!std::is_trivially_destructible<optional<T>>::value, "");
+ static_assert(!std::is_literal_type<optional<T>>::value, "");
+ {
+ X x;
+ optional<X> opt{x};
+ assert(X::dtor_called == false);
+ }
+ assert(X::dtor_called == true);
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp
new file mode 100644
index 000000000000..cee73da849b6
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <optional>
+
+// void reset() noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct X
+{
+ static bool dtor_called;
+ ~X() {dtor_called = true;}
+};
+
+bool X::dtor_called = false;
+
+int main()
+{
+ {
+ optional<int> opt;
+ static_assert(noexcept(opt.reset()) == true, "");
+ opt.reset();
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ optional<int> opt(3);
+ opt.reset();
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ optional<X> opt;
+ static_assert(noexcept(opt.reset()) == true, "");
+ assert(X::dtor_called == false);
+ opt.reset();
+ assert(X::dtor_called == false);
+ assert(static_cast<bool>(opt) == false);
+ }
+ assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
+ {
+ optional<X> opt(X{});
+ X::dtor_called = false;
+ opt.reset();
+ assert(X::dtor_called == true);
+ assert(static_cast<bool>(opt) == false);
+ X::dtor_called = false;
+ }
+ assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp
new file mode 100644
index 000000000000..9820d50f632e
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr explicit optional<T>::operator bool() const noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using std::optional;
+ {
+ const optional<int> opt; ((void)opt);
+ ASSERT_NOEXCEPT(bool(opt));
+ static_assert(!std::is_convertible<optional<int>, bool>::value, "");
+ }
+ {
+ constexpr optional<int> opt;
+ static_assert(!opt, "");
+ }
+ {
+ constexpr optional<int> opt(0);
+ static_assert(opt, "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp
new file mode 100644
index 000000000000..4087cfdf104e
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/dereference.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
+// <optional>
+
+// constexpr T& optional<T>::operator*() &;
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const& {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const&& {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ constexpr int test() {return 7;}
+};
+
+constexpr int
+test()
+{
+ optional<Y> opt{Y{}};
+ return (*opt).test();
+}
+
+int main()
+{
+ {
+ optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(*opt), X&);
+ // ASSERT_NOT_NOEXCEPT(*opt);
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator*() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ optional<X> opt(X{});
+ assert((*opt).test() == 4);
+ }
+ static_assert(test() == 7, "");
+#ifdef _LIBCPP_DEBUG
+ {
+ optional<X> opt;
+ assert((*opt).test() == 3);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp
new file mode 100644
index 000000000000..0779c9047c9e
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr const T& optional<T>::operator*() const &;
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const& {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const&& {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ int test() const {return 2;}
+};
+
+int main()
+{
+ {
+ const optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(*opt), X const&);
+ // ASSERT_NOT_NOEXCEPT(*opt);
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator*() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ constexpr optional<X> opt(X{});
+ static_assert((*opt).test() == 3, "");
+ }
+ {
+ constexpr optional<Y> opt(Y{});
+ assert((*opt).test() == 2);
+ }
+#ifdef _LIBCPP_DEBUG
+ {
+ const optional<X> opt;
+ assert((*opt).test() == 3);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp
new file mode 100644
index 000000000000..78fd992952c9
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr T&& optional<T>::operator*() const &&;
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const& {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const&& {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ int test() const && {return 2;}
+};
+
+int main()
+{
+ {
+ const optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(*std::move(opt)), X const &&);
+ // ASSERT_NOT_NOEXCEPT(*std::move(opt));
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator*() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ constexpr optional<X> opt(X{});
+ static_assert((*std::move(opt)).test() == 5, "");
+ }
+ {
+ constexpr optional<Y> opt(Y{});
+ assert((*std::move(opt)).test() == 2);
+ }
+#ifdef _LIBCPP_DEBUG
+ {
+ optional<X> opt;
+ assert((*std::move(opt)).test() == 5);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp
new file mode 100644
index 000000000000..2924123234a8
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.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
+// <optional>
+
+// constexpr T&& optional<T>::operator*() &&;
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const& {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const&& {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ constexpr int test() && {return 7;}
+};
+
+constexpr int
+test()
+{
+ optional<Y> opt{Y{}};
+ return (*std::move(opt)).test();
+}
+
+int main()
+{
+ {
+ optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(*std::move(opt)), X&&);
+ // ASSERT_NOT_NOEXCEPT(*std::move(opt));
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator*() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ optional<X> opt(X{});
+ assert((*std::move(opt)).test() == 6);
+ }
+ static_assert(test() == 7, "");
+#ifdef _LIBCPP_DEBUG
+ {
+ optional<X> opt;
+ assert((*std::move(opt)).test() == 3);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp
new file mode 100644
index 000000000000..5df295d01e22
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr bool optional<T>::has_value() const noexcept;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using std::optional;
+ {
+ const optional<int> opt; ((void)opt);
+ ASSERT_NOEXCEPT(opt.has_value());
+ ASSERT_SAME_TYPE(decltype(opt.has_value()), bool);
+ }
+ {
+ constexpr optional<int> opt;
+ static_assert(!opt.has_value(), "");
+ }
+ {
+ constexpr optional<int> opt(0);
+ static_assert(opt.has_value(), "");
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp
new file mode 100644
index 000000000000..2f1648c48c89
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr T* optional<T>::operator->();
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ int test() noexcept {return 3;}
+};
+
+struct Y
+{
+ constexpr int test() {return 3;}
+};
+
+constexpr int
+test()
+{
+ optional<Y> opt{Y{}};
+ return opt->test();
+}
+
+int main()
+{
+ {
+ std::optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), X*);
+ // ASSERT_NOT_NOEXCEPT(opt.operator->());
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator->() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ optional<X> opt(X{});
+ assert(opt->test() == 3);
+ }
+ {
+ static_assert(test() == 3, "");
+ }
+#ifdef _LIBCPP_DEBUG
+ {
+ optional<X> opt;
+ assert(opt->test() == 3);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp
new file mode 100644
index 000000000000..887edc7114eb
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.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
+// <optional>
+
+// constexpr const T* optional<T>::operator->() const;
+
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const {return 3;}
+};
+
+struct Y
+{
+ int test() const noexcept {return 2;}
+};
+
+struct Z
+{
+ const Z* operator&() const;
+ constexpr int test() const {return 1;}
+};
+
+int main()
+{
+ {
+ const std::optional<X> opt; ((void)opt);
+ ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*);
+ // ASSERT_NOT_NOEXCEPT(opt.operator->());
+ // FIXME: This assertion fails with GCC because it can see that
+ // (A) operator->() is constexpr, and
+ // (B) there is no path through the function that throws.
+ // It's arguable if this is the correct behavior for the noexcept
+ // operator.
+ // Regardless this function should still be noexcept(false) because
+ // it has a narrow contract.
+ }
+ {
+ constexpr optional<X> opt(X{});
+ static_assert(opt->test() == 3, "");
+ }
+ {
+ constexpr optional<Y> opt(Y{});
+ assert(opt->test() == 2);
+ }
+ {
+ constexpr optional<Z> opt(Z{});
+ static_assert(opt->test() == 1, "");
+ }
+#ifdef _LIBCPP_DEBUG
+ {
+ const optional<X> opt;
+ assert(opt->test() == 3);
+ assert(false);
+ }
+#endif // _LIBCPP_DEBUG
+}
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
new file mode 100644
index 000000000000..516a79db5f64
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value.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
+// <optional>
+
+// constexpr T& optional<T>::value() &;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::bad_optional_access;
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+ constexpr int test() const & {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const && {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ constexpr int test() & {return 7;}
+};
+
+constexpr int
+test()
+{
+ optional<Y> opt{Y{}};
+ return opt.value().test();
+}
+
+
+int main()
+{
+ {
+ optional<X> opt; ((void)opt);
+ ASSERT_NOT_NOEXCEPT(opt.value());
+ ASSERT_SAME_TYPE(decltype(opt.value()), X&);
+ }
+ {
+ optional<X> opt;
+ opt.emplace();
+ assert(opt.value().test() == 4);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<X> opt;
+ try
+ {
+ opt.value();
+ assert(false);
+ }
+ catch (const bad_optional_access&)
+ {
+ }
+ }
+#endif
+ static_assert(test() == 7, "");
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp
new file mode 100644
index 000000000000..6076c509fa41
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_const.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, c++11, c++14
+// <optional>
+
+// constexpr const T& optional<T>::value() const &;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct X
+{
+ constexpr int test() const {return 3;}
+ int test() {return 4;}
+};
+
+int main()
+{
+ {
+ constexpr optional<X> opt;
+ static_assert(opt.value().test() == 3, "");
+ }
+}
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
new file mode 100644
index 000000000000..d4038e4efa6b
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_const.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
+// <optional>
+
+// constexpr const T& optional<T>::value() const &;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::in_place_t;
+using std::in_place;
+using std::bad_optional_access;
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+ constexpr int test() const & {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const && {return 5;}
+ int test() && {return 6;}
+};
+
+int main()
+{
+ {
+ const optional<X> opt; ((void)opt);
+ ASSERT_NOT_NOEXCEPT(opt.value());
+ ASSERT_SAME_TYPE(decltype(opt.value()), X const&);
+ }
+ {
+ constexpr optional<X> opt(in_place);
+ static_assert(opt.value().test() == 3, "");
+ }
+ {
+ const optional<X> opt(in_place);
+ assert(opt.value().test() == 3);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ const optional<X> opt;
+ try
+ {
+ opt.value();
+ assert(false);
+ }
+ catch (const bad_optional_access&)
+ {
+ }
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..e189d3af6886
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.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
+// <optional>
+
+// constexpr const T& optional<T>::value() const &&;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::in_place_t;
+using std::in_place;
+using std::bad_optional_access;
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+ constexpr int test() const & {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const && {return 5;}
+ int test() && {return 6;}
+};
+
+int main()
+{
+ {
+ const optional<X> opt; ((void)opt);
+ ASSERT_NOT_NOEXCEPT(std::move(opt).value());
+ ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X const&&);
+ }
+ {
+ constexpr optional<X> opt(in_place);
+ static_assert(std::move(opt).value().test() == 5, "");
+ }
+ {
+ const optional<X> opt(in_place);
+ assert(std::move(opt).value().test() == 5);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ const optional<X> opt;
+ try
+ {
+ std::move(opt).value();
+ assert(false);
+ }
+ catch (const bad_optional_access&)
+ {
+ }
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp
new file mode 100644
index 000000000000..c219e9704716
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class U> T optional<T>::value_or(U&& v) &&;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::in_place_t;
+using std::in_place;
+
+struct Y
+{
+ int i_;
+
+ Y(int i) : i_(i) {}
+};
+
+struct X
+{
+ int i_;
+
+ X(int i) : i_(i) {}
+ X(X&& x) : i_(x.i_) {x.i_ = 0;}
+ X(const Y& y) : i_(y.i_) {}
+ X(Y&& y) : i_(y.i_+1) {}
+ friend constexpr bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_;}
+};
+
+int main()
+{
+ {
+ optional<X> opt(in_place, 2);
+ Y y(3);
+ assert(std::move(opt).value_or(y) == 2);
+ assert(*opt == 0);
+ }
+ {
+ optional<X> opt(in_place, 2);
+ assert(std::move(opt).value_or(Y(3)) == 2);
+ assert(*opt == 0);
+ }
+ {
+ optional<X> opt;
+ Y y(3);
+ assert(std::move(opt).value_or(y) == 3);
+ assert(!opt);
+ }
+ {
+ optional<X> opt;
+ assert(std::move(opt).value_or(Y(3)) == 4);
+ assert(!opt);
+ }
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp
new file mode 100644
index 000000000000..36a85811ba49
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class U> constexpr T optional<T>::value_or(U&& v) const&;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct Y
+{
+ int i_;
+
+ constexpr Y(int i) : i_(i) {}
+};
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+ constexpr X(const Y& y) : i_(y.i_) {}
+ constexpr X(Y&& y) : i_(y.i_+1) {}
+ friend constexpr bool operator==(const X& x, const X& y)
+ {return x.i_ == y.i_;}
+};
+
+int main()
+{
+ {
+ constexpr optional<X> opt(2);
+ constexpr Y y(3);
+ static_assert(opt.value_or(y) == 2, "");
+ }
+ {
+ constexpr optional<X> opt(2);
+ static_assert(opt.value_or(Y(3)) == 2, "");
+ }
+ {
+ constexpr optional<X> opt;
+ constexpr Y y(3);
+ static_assert(opt.value_or(y) == 3, "");
+ }
+ {
+ constexpr optional<X> opt;
+ static_assert(opt.value_or(Y(3)) == 4, "");
+ }
+ {
+ const optional<X> opt(2);
+ const Y y(3);
+ assert(opt.value_or(y) == 2);
+ }
+ {
+ const optional<X> opt(2);
+ assert(opt.value_or(Y(3)) == 2);
+ }
+ {
+ const optional<X> opt;
+ const Y y(3);
+ assert(opt.value_or(y) == 3);
+ }
+ {
+ const optional<X> opt;
+ assert(opt.value_or(Y(3)) == 4);
+ }
+}
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
new file mode 100644
index 000000000000..2ef485b7fe50
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// constexpr T& optional<T>::value() &&;
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+using std::optional;
+using std::bad_optional_access;
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+ constexpr int test() const & {return 3;}
+ int test() & {return 4;}
+ constexpr int test() const && {return 5;}
+ int test() && {return 6;}
+};
+
+struct Y
+{
+ constexpr int test() && {return 7;}
+};
+
+constexpr int
+test()
+{
+ optional<Y> opt{Y{}};
+ return std::move(opt).value().test();
+}
+
+int main()
+{
+ {
+ optional<X> opt; ((void)opt);
+ ASSERT_NOT_NOEXCEPT(std::move(opt).value());
+ ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&);
+ }
+ {
+ optional<X> opt;
+ opt.emplace();
+ assert(std::move(opt).value().test() == 6);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<X> opt;
+ try
+ {
+ std::move(opt).value();
+ assert(false);
+ }
+ catch (const bad_optional_access&)
+ {
+ }
+ }
+#endif
+ static_assert(test() == 7, "");
+}
diff --git a/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp
new file mode 100644
index 000000000000..26041259fa93
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp
@@ -0,0 +1,306 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// void swap(optional&)
+// noexcept(is_nothrow_move_constructible<T>::value &&
+// is_nothrow_swappable<T>::value)
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+class X
+{
+ int i_;
+public:
+ static unsigned dtor_called;
+ X(int i) : i_(i) {}
+ X(X&& x) = default;
+ X& operator=(X&&) = default;
+ ~X() {++dtor_called;}
+
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+unsigned X::dtor_called = 0;
+
+class Y
+{
+ int i_;
+public:
+ static unsigned dtor_called;
+ Y(int i) : i_(i) {}
+ Y(Y&&) = default;
+ ~Y() {++dtor_called;}
+
+ friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
+};
+
+unsigned Y::dtor_called = 0;
+
+class Z
+{
+ int i_;
+public:
+ Z(int i) : i_(i) {}
+ Z(Z&&) {TEST_THROW(7);}
+
+ friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend void swap(Z&, Z&) {TEST_THROW(6);}
+};
+
+
+int main()
+{
+ {
+ optional<int> opt1;
+ optional<int> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<int> opt1(1);
+ optional<int> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<int> opt1;
+ optional<int> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<int> opt1(1);
+ optional<int> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<X> opt1;
+ optional<X> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ assert(X::dtor_called == 0);
+ }
+ {
+ optional<X> opt1(1);
+ optional<X> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ X::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(X::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<X> opt1;
+ optional<X> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ X::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(X::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<X> opt1(1);
+ optional<X> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ X::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(X::dtor_called == 1); // from inside std::swap
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Y> opt1;
+ optional<Y> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ assert(Y::dtor_called == 0);
+ }
+ {
+ optional<Y> opt1(1);
+ optional<Y> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ Y::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(Y::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Y> opt1;
+ optional<Y> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ Y::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(Y::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<Y> opt1(1);
+ optional<Y> opt2(2);
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ Y::dtor_called = 0;
+ opt1.swap(opt2);
+ assert(Y::dtor_called == 0);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Z> opt1;
+ optional<Z> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ opt1.swap(opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<Z> opt1;
+ opt1.emplace(1);
+ optional<Z> opt2;
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ try
+ {
+ opt1.swap(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 7);
+ }
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<Z> opt1;
+ optional<Z> opt2;
+ opt2.emplace(2);
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ try
+ {
+ opt1.swap(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 7);
+ }
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ }
+ {
+ optional<Z> opt1;
+ opt1.emplace(1);
+ optional<Z> opt2;
+ opt2.emplace(2);
+ static_assert(noexcept(opt1.swap(opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ try
+ {
+ opt1.swap(opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ }
+#endif
+}
diff --git a/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp b/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp
new file mode 100644
index 000000000000..8a2c77af0ec1
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// T shall be an object type and shall satisfy the requirements of Destructible
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+private:
+ ~X() {}
+};
+
+int main()
+{
+ using std::optional;
+ {
+ // expected-error@optional:* 2 {{static_assert failed "instantiation of optional with a reference type is ill-formed}}
+ optional<int&> opt1;
+ optional<int&&> opt2;
+ }
+ {
+ // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed"}}
+ optional<X> opt3;
+ }
+ {
+ // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}}
+ // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}}
+ optional<void()> opt4;
+ }
+ {
+ // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}}
+ // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}}
+ // expected-error@optional:* 1+ {{cannot form a reference to 'void'}}
+ optional<const void> opt4;
+ }
+ // FIXME these are garbage diagnostics that Clang should not produce
+ // expected-error@optional:* 0+ {{is not a base class}}
+}
diff --git a/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp b/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp
new file mode 100644
index 000000000000..fdd0f154f0e5
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/special_member_gen.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
+// <optional>
+
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#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_copy_constructible_v<T> && std::is_copy_assignable_v<T>) ||
+ (std::is_move_constructible_v<T> && std::is_move_assignable_v<T>)),
+ "optional<T> is move assignable if and only if T is both move assignable and "
+ "move constructible, or both copy constructible and copy assignable.");
+};
+
+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.object/types.pass.cpp b/test/std/utilities/optional/optional.object/types.pass.cpp
new file mode 100644
index 000000000000..0230a13dded1
--- /dev/null
+++ b/test/std/utilities/optional/optional.object/types.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T>
+// class optional
+// {
+// public:
+// typedef T value_type;
+// ...
+
+#include <optional>
+#include <type_traits>
+
+using std::optional;
+
+template <class Opt, class T>
+void
+test()
+{
+ static_assert(std::is_same<typename Opt::value_type, T>::value, "");
+}
+
+int main()
+{
+ test<optional<int>, int>();
+ test<optional<const int>, const int>();
+ test<optional<double>, double>();
+ test<optional<const double>, const double>();
+}
diff --git a/test/std/utilities/optional/optional.relops/equal.pass.cpp b/test/std/utilities/optional/optional.relops/equal.pass.cpp
new file mode 100644
index 000000000000..6650b6720a8e
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/equal.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
+// <optional>
+
+// template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator == ( const X &lhs, const X &rhs )
+ { return lhs.i_ == rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( o1 == o1 , "" );
+ static_assert ( o1 == o2 , "" );
+ static_assert ( !(o1 == o3), "" );
+ static_assert ( !(o1 == o4), "" );
+ static_assert ( !(o1 == o5), "" );
+
+ static_assert ( o2 == o1 , "" );
+ static_assert ( o2 == o2 , "" );
+ static_assert ( !(o2 == o3), "" );
+ static_assert ( !(o2 == o4), "" );
+ static_assert ( !(o2 == o5), "" );
+
+ static_assert ( !(o3 == o1), "" );
+ static_assert ( !(o3 == o2), "" );
+ static_assert ( o3 == o3 , "" );
+ static_assert ( !(o3 == o4), "" );
+ static_assert ( o3 == o5 , "" );
+
+ static_assert ( !(o4 == o1), "" );
+ static_assert ( !(o4 == o2), "" );
+ static_assert ( !(o4 == o3), "" );
+ static_assert ( o4 == o4 , "" );
+ static_assert ( !(o4 == o5), "" );
+
+ static_assert ( !(o5 == o1), "" );
+ static_assert ( !(o5 == o2), "" );
+ static_assert ( o5 == o3 , "" );
+ static_assert ( !(o5 == o4), "" );
+ static_assert ( o5 == o5 , "" );
+
+ }
+}
diff --git a/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp b/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
new file mode 100644
index 000000000000..f9b30449638a
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator>= (const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator >= ( const X &lhs, const X &rhs )
+ { return lhs.i_ >= rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef optional<X> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( (o1 >= o1), "" );
+ static_assert ( (o1 >= o2), "" );
+ static_assert ( !(o1 >= o3), "" );
+ static_assert ( !(o1 >= o4), "" );
+ static_assert ( !(o1 >= o5), "" );
+
+ static_assert ( (o2 >= o1), "" );
+ static_assert ( (o2 >= o2), "" );
+ static_assert ( !(o2 >= o3), "" );
+ static_assert ( !(o2 >= o4), "" );
+ static_assert ( !(o2 >= o5), "" );
+
+ static_assert ( (o3 >= o1), "" );
+ static_assert ( (o3 >= o2), "" );
+ static_assert ( (o3 >= o3), "" );
+ static_assert ( !(o3 >= o4), "" );
+ static_assert ( (o3 >= o5), "" );
+
+ static_assert ( (o4 >= o1), "" );
+ static_assert ( (o4 >= o2), "" );
+ static_assert ( (o4 >= o3), "" );
+ static_assert ( (o4 >= o4), "" );
+ static_assert ( (o4 >= o5), "" );
+
+ static_assert ( (o5 >= o1), "" );
+ static_assert ( (o5 >= o2), "" );
+ static_assert ( (o5 >= o3), "" );
+ static_assert ( !(o5 >= o4), "" );
+ static_assert ( (o5 >= o5), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.relops/greater_than.pass.cpp b/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
new file mode 100644
index 000000000000..8a27eb471f28
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator> (const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator > ( const X &lhs, const X &rhs )
+ { return lhs.i_ > rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef optional<X> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( !(o1 > o1), "" );
+ static_assert ( !(o1 > o2), "" );
+ static_assert ( !(o1 > o3), "" );
+ static_assert ( !(o1 > o4), "" );
+ static_assert ( !(o1 > o5), "" );
+
+ static_assert ( !(o2 > o1), "" );
+ static_assert ( !(o2 > o2), "" );
+ static_assert ( !(o2 > o3), "" );
+ static_assert ( !(o2 > o4), "" );
+ static_assert ( !(o2 > o5), "" );
+
+ static_assert ( (o3 > o1), "" );
+ static_assert ( (o3 > o2), "" );
+ static_assert ( !(o3 > o3), "" );
+ static_assert ( !(o3 > o4), "" );
+ static_assert ( !(o3 > o5), "" );
+
+ static_assert ( (o4 > o1), "" );
+ static_assert ( (o4 > o2), "" );
+ static_assert ( (o4 > o3), "" );
+ static_assert ( !(o4 > o4), "" );
+ static_assert ( (o4 > o5), "" );
+
+ static_assert ( (o5 > o1), "" );
+ static_assert ( (o5 > o2), "" );
+ static_assert ( !(o5 > o3), "" );
+ static_assert ( !(o5 > o4), "" );
+ static_assert ( !(o5 > o5), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.relops/less_equal.pass.cpp b/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
new file mode 100644
index 000000000000..a7d594dd34a2
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator<= (const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator <= ( const X &lhs, const X &rhs )
+ { return lhs.i_ <= rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef optional<X> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( (o1 <= o1), "" );
+ static_assert ( (o1 <= o2), "" );
+ static_assert ( (o1 <= o3), "" );
+ static_assert ( (o1 <= o4), "" );
+ static_assert ( (o1 <= o5), "" );
+
+ static_assert ( (o2 <= o1), "" );
+ static_assert ( (o2 <= o2), "" );
+ static_assert ( (o2 <= o3), "" );
+ static_assert ( (o2 <= o4), "" );
+ static_assert ( (o2 <= o5), "" );
+
+ static_assert ( !(o3 <= o1), "" );
+ static_assert ( !(o3 <= o2), "" );
+ static_assert ( (o3 <= o3), "" );
+ static_assert ( (o3 <= o4), "" );
+ static_assert ( (o3 <= o5), "" );
+
+ static_assert ( !(o4 <= o1), "" );
+ static_assert ( !(o4 <= o2), "" );
+ static_assert ( !(o4 <= o3), "" );
+ static_assert ( (o4 <= o4), "" );
+ static_assert ( !(o4 <= o5), "" );
+
+ static_assert ( !(o5 <= o1), "" );
+ static_assert ( !(o5 <= o2), "" );
+ static_assert ( (o5 <= o3), "" );
+ static_assert ( (o5 <= o4), "" );
+ static_assert ( (o5 <= o5), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.relops/less_than.pass.cpp b/test/std/utilities/optional/optional.relops/less_than.pass.cpp
new file mode 100644
index 000000000000..deffa5e849f9
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/less_than.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T> constexpr bool operator< (const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator < ( const X &lhs, const X &rhs )
+ { return lhs.i_ < rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef optional<X> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( !(o1 < o1), "" );
+ static_assert ( !(o1 < o2), "" );
+ static_assert ( (o1 < o3), "" );
+ static_assert ( (o1 < o4), "" );
+ static_assert ( (o1 < o5), "" );
+
+ static_assert ( !(o2 < o1), "" );
+ static_assert ( !(o2 < o2), "" );
+ static_assert ( (o2 < o3), "" );
+ static_assert ( (o2 < o4), "" );
+ static_assert ( (o2 < o5), "" );
+
+ static_assert ( !(o3 < o1), "" );
+ static_assert ( !(o3 < o2), "" );
+ static_assert ( !(o3 < o3), "" );
+ static_assert ( (o3 < o4), "" );
+ static_assert ( !(o3 < o5), "" );
+
+ static_assert ( !(o4 < o1), "" );
+ static_assert ( !(o4 < o2), "" );
+ static_assert ( !(o4 < o3), "" );
+ static_assert ( !(o4 < o4), "" );
+ static_assert ( !(o4 < o5), "" );
+
+ static_assert ( !(o5 < o1), "" );
+ static_assert ( !(o5 < o2), "" );
+ static_assert ( !(o5 < o3), "" );
+ static_assert ( (o5 < o4), "" );
+ static_assert ( !(o5 < o5), "" );
+ }
+}
diff --git a/test/std/utilities/optional/optional.relops/not_equal.pass.cpp b/test/std/utilities/optional/optional.relops/not_equal.pass.cpp
new file mode 100644
index 000000000000..fd11b2a207ca
--- /dev/null
+++ b/test/std/utilities/optional/optional.relops/not_equal.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
+// <optional>
+
+// template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+using std::optional;
+
+struct X
+{
+ int i_;
+
+ constexpr X(int i) : i_(i) {}
+};
+
+constexpr bool operator != ( const X &lhs, const X &rhs )
+ { return lhs.i_ != rhs.i_ ; }
+
+int main()
+{
+ {
+ typedef X T;
+ typedef optional<T> O;
+
+ constexpr O o1; // disengaged
+ constexpr O o2; // disengaged
+ constexpr O o3{1}; // engaged
+ constexpr O o4{2}; // engaged
+ constexpr O o5{1}; // engaged
+
+ static_assert ( !(o1 != o1), "" );
+ static_assert ( !(o1 != o2), "" );
+ static_assert ( (o1 != o3), "" );
+ static_assert ( (o1 != o4), "" );
+ static_assert ( (o1 != o5), "" );
+
+ static_assert ( !(o2 != o1), "" );
+ static_assert ( !(o2 != o2), "" );
+ static_assert ( (o2 != o3), "" );
+ static_assert ( (o2 != o4), "" );
+ static_assert ( (o2 != o5), "" );
+
+ static_assert ( (o3 != o1), "" );
+ static_assert ( (o3 != o2), "" );
+ static_assert ( !(o3 != o3), "" );
+ static_assert ( (o3 != o4), "" );
+ static_assert ( !(o3 != o5), "" );
+
+ static_assert ( (o4 != o1), "" );
+ static_assert ( (o4 != o2), "" );
+ static_assert ( (o4 != o3), "" );
+ static_assert ( !(o4 != o4), "" );
+ static_assert ( (o4 != o5), "" );
+
+ static_assert ( (o5 != o1), "" );
+ static_assert ( (o5 != o2), "" );
+ static_assert ( !(o5 != o3), "" );
+ static_assert ( (o5 != o4), "" );
+ static_assert ( !(o5 != o5), "" );
+
+ }
+}
diff --git a/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
new file mode 100644
index 000000000000..3fbf19f8ee1b
--- /dev/null
+++ b/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T>
+// constexpr optional<decay_t<T>> make_optional(T&& v);
+
+#include <optional>
+#include <string>
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ using std::optional;
+ using std::make_optional;
+ {
+ int arr[10]; ((void)arr);
+ ASSERT_SAME_TYPE(decltype(make_optional(arr)), optional<int*>);
+ }
+ {
+ constexpr auto opt = make_optional(2);
+ ASSERT_SAME_TYPE(decltype(opt), const optional<int>);
+ static_assert(opt.value() == 2);
+ }
+ {
+ optional<int> opt = make_optional(2);
+ assert(*opt == 2);
+ }
+ {
+ std::string s("123");
+ optional<std::string> opt = make_optional(s);
+ assert(*opt == s);
+ }
+ {
+ std::unique_ptr<int> s(new int(3));
+ optional<std::unique_ptr<int>> opt = make_optional(std::move(s));
+ assert(**opt == 3);
+ assert(s == nullptr);
+ }
+}
diff --git a/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp b/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp
new file mode 100644
index 000000000000..bdfeefbcc1d8
--- /dev/null
+++ b/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T, class... Args>
+// constexpr optional<T> make_optional(Args&&... args);
+
+#include <optional>
+#include <string>
+#include <memory>
+#include <cassert>
+
+int main()
+{
+ using std::optional;
+ using std::make_optional;
+
+ {
+ constexpr auto opt = make_optional<int>('a');
+ static_assert(*opt == int('a'), "");
+ }
+ {
+ std::string s("123");
+ auto opt = make_optional<std::string>(s);
+ assert(*opt == s);
+ }
+ {
+ std::unique_ptr<int> s(new int(3));
+ auto opt = make_optional<std::unique_ptr<int>>(std::move(s));
+ assert(**opt == 3);
+ assert(s == nullptr);
+ }
+ {
+ auto opt = make_optional<std::string>(4, 'X');
+ assert(*opt == "XXXX");
+ }
+}
diff --git a/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp b/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp
new file mode 100644
index 000000000000..e6ed0129ddc7
--- /dev/null
+++ b/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// template <class T, class U, class... Args>
+// constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
+
+#include <optional>
+#include <string>
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct TestT {
+ int x;
+ int size;
+ constexpr TestT(std::initializer_list<int> il) : x(*il.begin()), size(static_cast<int>(il.size())) {}
+ constexpr TestT(std::initializer_list<int> il, const int*)
+ : x(*il.begin()), size(static_cast<int>(il.size())) {}
+};
+
+int main()
+{
+ using std::make_optional;
+ {
+ constexpr auto opt = make_optional<TestT>({42, 2, 3});
+ ASSERT_SAME_TYPE(decltype(opt), const std::optional<TestT>);
+ static_assert(opt->x == 42, "");
+ static_assert(opt->size == 3, "");
+ }
+ {
+ constexpr auto opt = make_optional<TestT>({42, 2, 3}, nullptr);
+ static_assert(opt->x == 42, "");
+ static_assert(opt->size == 3, "");
+ }
+ {
+ auto opt = make_optional<std::string>({'1', '2', '3'});
+ assert(*opt == "123");
+ }
+ {
+ auto opt = make_optional<std::string>({'a', 'b', 'c'}, std::allocator<char>{});
+ assert(*opt == "abc");
+ }
+}
diff --git a/test/std/utilities/optional/optional.specalg/swap.pass.cpp b/test/std/utilities/optional/optional.specalg/swap.pass.cpp
new file mode 100644
index 000000000000..31779243e32a
--- /dev/null
+++ b/test/std/utilities/optional/optional.specalg/swap.pass.cpp
@@ -0,0 +1,352 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under 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>
+
+// template <class T> void swap(optional<T>& x, optional<T>& y)
+// noexcept(noexcept(x.swap(y)));
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "archetypes.hpp"
+
+using std::optional;
+
+class X
+{
+ int i_;
+public:
+ static unsigned dtor_called;
+ X(int i) : i_(i) {}
+ X(X&& x) = default;
+ X& operator=(X&&) = default;
+ ~X() {++dtor_called;}
+
+ friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+};
+
+unsigned X::dtor_called = 0;
+
+class Y
+{
+ int i_;
+public:
+ static unsigned dtor_called;
+ Y(int i) : i_(i) {}
+ Y(Y&&) = default;
+ ~Y() {++dtor_called;}
+
+ friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
+};
+
+unsigned Y::dtor_called = 0;
+
+class Z
+{
+ int i_;
+public:
+ Z(int i) : i_(i) {}
+ Z(Z&&) { TEST_THROW(7);}
+
+ friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend void swap(Z&, Z&) { TEST_THROW(6);}
+};
+
+
+struct NonSwappable {
+ NonSwappable(NonSwappable const&) = delete;
+};
+void swap(NonSwappable&, NonSwappable&) = delete;
+
+void test_swap_sfinae() {
+ using std::optional;
+ {
+ using T = TestTypes::TestType;
+ static_assert(std::is_swappable_v<optional<T>>, "");
+ }
+ {
+ using T = TestTypes::MoveOnly;
+ static_assert(std::is_swappable_v<optional<T>>, "");
+ }
+ {
+ using T = TestTypes::Copyable;
+ static_assert(std::is_swappable_v<optional<T>>, "");
+ }
+ {
+ using T = TestTypes::NoCtors;
+ static_assert(!std::is_swappable_v<optional<T>>, "");
+ }
+ {
+ using T = NonSwappable;
+ static_assert(!std::is_swappable_v<optional<T>>, "");
+ }
+ {
+ // Even thought CopyOnly has deleted move operations, those operations
+ // cause optional<CopyOnly> to have implicitly deleted move operations
+ // that decay into copies.
+ using T = TestTypes::CopyOnly;
+ using Opt = optional<T>;
+ T::reset();
+ Opt L(101), R(42);
+ T::reset_constructors();
+ std::swap(L, R);
+ assert(L->value == 42);
+ assert(R->value == 101);
+ assert(T::copy_constructed == 1);
+ assert(T::constructed == T::copy_constructed);
+ assert(T::assigned == 2);
+ assert(T::assigned == T::copy_assigned);
+ }
+}
+
+int main()
+{
+ test_swap_sfinae();
+ {
+ optional<int> opt1;
+ optional<int> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<int> opt1(1);
+ optional<int> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<int> opt1;
+ optional<int> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<int> opt1(1);
+ optional<int> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<X> opt1;
+ optional<X> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ assert(X::dtor_called == 0);
+ }
+ {
+ optional<X> opt1(1);
+ optional<X> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ X::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(X::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<X> opt1;
+ optional<X> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ X::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(X::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<X> opt1(1);
+ optional<X> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == true, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ X::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(X::dtor_called == 1); // from inside std::swap
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Y> opt1;
+ optional<Y> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ assert(Y::dtor_called == 0);
+ }
+ {
+ optional<Y> opt1(1);
+ optional<Y> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ Y::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(Y::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Y> opt1;
+ optional<Y> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ Y::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(Y::dtor_called == 1);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<Y> opt1(1);
+ optional<Y> opt2(2);
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ Y::dtor_called = 0;
+ swap(opt1, opt2);
+ assert(Y::dtor_called == 0);
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 2);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 1);
+ }
+ {
+ optional<Z> opt1;
+ optional<Z> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ swap(opt1, opt2);
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == false);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ optional<Z> opt1;
+ opt1.emplace(1);
+ optional<Z> opt2;
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ try
+ {
+ swap(opt1, opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 7);
+ }
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == false);
+ }
+ {
+ optional<Z> opt1;
+ optional<Z> opt2;
+ opt2.emplace(2);
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ try
+ {
+ swap(opt1, opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 7);
+ }
+ assert(static_cast<bool>(opt1) == false);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ }
+ {
+ optional<Z> opt1;
+ opt1.emplace(1);
+ optional<Z> opt2;
+ opt2.emplace(2);
+ static_assert(noexcept(swap(opt1, opt2)) == false, "");
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ try
+ {
+ swap(opt1, opt2);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 6);
+ }
+ assert(static_cast<bool>(opt1) == true);
+ assert(*opt1 == 1);
+ assert(static_cast<bool>(opt2) == true);
+ assert(*opt2 == 2);
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
diff --git a/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp b/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp
new file mode 100644
index 000000000000..20c90c7e34fd
--- /dev/null
+++ b/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
+
+// A program that necessitates the instantiation of template optional for
+// (possibly cv-qualified) in_place_t is ill-formed.
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::in_place_t;
+ using std::in_place;
+
+ optional<in_place_t> opt; // expected-note {{requested here}}
+ // expected-error@optional:* {{"instantiation of optional with in_place_t is ill-formed"}}
+}
diff --git a/test/std/utilities/utility/forward/forward1.fail.cpp b/test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp
index 43884d54bf86..687625e8b673 100644
--- a/test/std/utilities/utility/forward/forward1.fail.cpp
+++ b/test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp
@@ -7,18 +7,16 @@
//
//===----------------------------------------------------------------------===//
-// test forward
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// <optional>
-#include <utility>
+// #include <initializer_list>
-struct A
-{
-};
-
-A source() {return A();}
-const A csource() {return A();}
+#include <optional>
int main()
{
- std::forward<A&>(source()); // error
+ using std::optional;
+
+ std::initializer_list<int> list;
}
diff --git a/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp b/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp
new file mode 100644
index 000000000000..56a30ccb0db9
--- /dev/null
+++ b/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.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
+// <optional>
+
+// A program that necessitates the instantiation of template optional for
+// (possibly cv-qualified) nullopt_t is ill-formed.
+
+#include <optional>
+
+int main()
+{
+ using std::optional;
+ using std::nullopt_t;
+ using std::nullopt;
+
+ optional<nullopt_t> opt; // expected-note 1 {{requested here}}
+ optional<const nullopt_t> opt1; // expected-note 1 {{requested here}}
+ optional<nullopt_t &> opt2; // expected-note 1 {{requested here}}
+ optional<nullopt_t &&> opt3; // expected-note 1 {{requested here}}
+ // expected-error@optional:* 4 {{instantiation of optional with nullopt_t is ill-formed}}
+}
diff --git a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
index 1b121c5fb928..3ba88ee2db53 100644
--- a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
@@ -12,6 +12,7 @@
#include <bitset>
#include <cassert>
#include <algorithm> // for 'min' and 'max'
+#include <cstddef>
#include "test_macros.h"
@@ -21,9 +22,9 @@ void test_val_ctor()
{
TEST_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL);
assert(v.size() == N);
- unsigned M = std::min<std::size_t>(N, 64);
+ std::size_t M = std::min<std::size_t>(N, 64);
for (std::size_t i = 0; i < M; ++i)
- assert(v[i] == (i & 1));
+ assert(v[i] == ((i & 1) != 0));
for (std::size_t i = M; i < N; ++i)
assert(v[i] == false);
}
diff --git a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
index 88ce8e943caf..18a64a214a45 100644
--- a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// test bitset<N>& flip(size_t pos);
#include <bitset>
#include <cstdlib>
#include <cassert>
+#include "test_macros.h"
+
template <std::size_t N>
std::bitset<N>
make_bitset()
@@ -25,11 +26,15 @@ make_bitset()
}
template <std::size_t N>
-void test_flip_one()
+void test_flip_one(bool test_throws)
{
std::bitset<N> v = make_bitset<N>();
+#ifdef TEST_HAS_NO_EXCEPTIONS
+ if (test_throws) return;
+#else
try
{
+#endif
v.flip(50);
bool b = v[50];
if (50 >= v.size())
@@ -39,21 +44,25 @@ void test_flip_one()
assert(v[50] != b);
v.flip(50);
assert(v[50] == b);
+ assert(!test_throws);
+#ifndef TEST_HAS_NO_EXCEPTIONS
}
catch (std::out_of_range&)
{
+ assert(test_throws);
}
+#endif
}
int main()
{
- test_flip_one<0>();
- test_flip_one<1>();
- test_flip_one<31>();
- test_flip_one<32>();
- test_flip_one<33>();
- test_flip_one<63>();
- test_flip_one<64>();
- test_flip_one<65>();
- test_flip_one<1000>();
+ test_flip_one<0>(true);
+ test_flip_one<1>(true);
+ test_flip_one<31>(true);
+ test_flip_one<32>(true);
+ test_flip_one<33>(true);
+ test_flip_one<63>(false);
+ test_flip_one<64>(false);
+ test_flip_one<65>(false);
+ test_flip_one<1000>(false);
}
diff --git a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
index f01d35b9a33c..6847694e4b73 100644
--- a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
@@ -7,18 +7,23 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// test bitset<N>& reset(size_t pos);
#include <bitset>
#include <cassert>
+#include "test_macros.h"
+
template <std::size_t N>
-void test_reset_one()
+void test_reset_one(bool test_throws)
{
std::bitset<N> v;
+#ifdef TEST_HAS_NO_EXCEPTIONS
+ if (test_throws) return;
+#else
try
{
+#endif
v.set();
v.reset(50);
if (50 >= v.size())
@@ -28,21 +33,25 @@ void test_reset_one()
assert(!v[i]);
else
assert(v[i]);
+ assert(!test_throws);
+#ifndef TEST_HAS_NO_EXCEPTIONS
}
catch (std::out_of_range&)
{
+ assert(test_throws);
}
+#endif
}
int main()
{
- test_reset_one<0>();
- test_reset_one<1>();
- test_reset_one<31>();
- test_reset_one<32>();
- test_reset_one<33>();
- test_reset_one<63>();
- test_reset_one<64>();
- test_reset_one<65>();
- test_reset_one<1000>();
+ test_reset_one<0>(true);
+ test_reset_one<1>(true);
+ test_reset_one<31>(true);
+ test_reset_one<32>(true);
+ test_reset_one<33>(true);
+ test_reset_one<63>(false);
+ test_reset_one<64>(false);
+ test_reset_one<65>(false);
+ test_reset_one<1000>(false);
}
diff --git a/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
index debe5431d8d0..1c8d6a1c32a4 100644
--- a/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
@@ -7,47 +7,60 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// test bitset<N>& set(size_t pos, bool val = true);
#include <bitset>
#include <cassert>
+#include "test_macros.h"
+
template <std::size_t N>
-void test_set_one()
+void test_set_one(bool test_throws)
{
std::bitset<N> v;
+#ifdef TEST_HAS_NO_EXCEPTIONS
+ if (test_throws) return;
+#else
try
+#endif
{
v.set(50);
if (50 >= v.size())
assert(false);
assert(v[50]);
+ assert(!test_throws);
}
+#ifndef TEST_HAS_NO_EXCEPTIONS
catch (std::out_of_range&)
{
+ assert(test_throws);
}
try
+#endif
{
v.set(50, false);
if (50 >= v.size())
assert(false);
assert(!v[50]);
+ assert(!test_throws);
}
+#ifndef TEST_HAS_NO_EXCEPTIONS
catch (std::out_of_range&)
{
+ assert(test_throws);
}
+#endif
}
int main()
{
- test_set_one<0>();
- test_set_one<1>();
- test_set_one<31>();
- test_set_one<32>();
- test_set_one<33>();
- test_set_one<63>();
- test_set_one<64>();
- test_set_one<65>();
- test_set_one<1000>();
+ test_set_one<0>(true);
+ test_set_one<1>(true);
+ test_set_one<31>(true);
+ test_set_one<32>(true);
+ test_set_one<33>(true);
+ test_set_one<63>(false);
+ test_set_one<64>(false);
+ test_set_one<65>(false);
+ test_set_one<1000>(false);
}
diff --git a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
index 161afd11c291..1a2d70613e1f 100644
--- a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: libcpp-no-exceptions
// test constexpr bool test(size_t pos) const;
#include <bitset>
#include <cstdlib>
#include <cassert>
+#include "test_macros.h"
+
template <std::size_t N>
std::bitset<N>
make_bitset()
@@ -25,30 +26,38 @@ make_bitset()
}
template <std::size_t N>
-void test_test()
+void test_test(bool test_throws)
{
const std::bitset<N> v1 = make_bitset<N>();
+#ifdef TEST_HAS_NO_EXCEPTIONS
+ if (test_throws) return;
+#else
try
{
+#endif
bool b = v1.test(50);
if (50 >= v1.size())
assert(false);
assert(b == v1[50]);
+ assert(!test_throws);
+#ifndef TEST_HAS_NO_EXCEPTIONS
}
catch (std::out_of_range&)
{
+ assert(test_throws);
}
+#endif
}
int main()
{
- test_test<0>();
- test_test<1>();
- test_test<31>();
- test_test<32>();
- test_test<33>();
- test_test<63>();
- test_test<64>();
- test_test<65>();
- test_test<1000>();
+ test_test<0>(true);
+ test_test<1>(true);
+ test_test<31>(true);
+ test_test<32>(true);
+ test_test<33>(true);
+ test_test<63>(false);
+ test_test<64>(false);
+ test_test<65>(false);
+ test_test<1000>(false);
}
diff --git a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
index 80792d919ccf..d86a10c6df13 100644
--- a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
@@ -33,7 +33,7 @@ void test_op_and()
std::bitset<N> v1 = make_bitset<N>();
std::bitset<N> v2 = make_bitset<N>();
std::bitset<N> v3 = v1;
- assert((v1 & v2) == (v3 &= v2));;
+ assert((v1 & v2) == (v3 &= v2));
}
int main()
diff --git a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
index 65a7004acb86..0a8024d5eb9b 100644
--- a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
@@ -33,7 +33,7 @@ void test_op_not()
std::bitset<N> v1 = make_bitset<N>();
std::bitset<N> v2 = make_bitset<N>();
std::bitset<N> v3 = v1;
- assert((v1 ^ v2) == (v3 ^= v2));;
+ assert((v1 ^ v2) == (v3 ^= v2));
}
int main()
diff --git a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
index dcabaa4a9a4d..449115edd757 100644
--- a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
@@ -33,7 +33,7 @@ void test_op_or()
std::bitset<N> v1 = make_bitset<N>();
std::bitset<N> v2 = make_bitset<N>();
std::bitset<N> v3 = v1;
- assert((v1 | v2) == (v3 |= v2));;
+ assert((v1 | v2) == (v3 |= v2));
}
int main()
diff --git a/test/std/utilities/time/rep.h b/test/std/utilities/time/rep.h
index 2ec3514ab567..1c76582d3725 100644
--- a/test/std/utilities/time/rep.h
+++ b/test/std/utilities/time/rep.h
@@ -10,15 +10,17 @@
#ifndef REP_H
#define REP_H
+#include "test_macros.h"
+
class Rep
{
int data_;
public:
- _LIBCPP_CONSTEXPR Rep() : data_(-1) {}
- explicit _LIBCPP_CONSTEXPR Rep(int i) : data_(i) {}
+ TEST_CONSTEXPR Rep() : data_(-1) {}
+ explicit TEST_CONSTEXPR Rep(int i) : data_(i) {}
- bool _LIBCPP_CONSTEXPR operator==(int i) const {return data_ == i;}
- bool _LIBCPP_CONSTEXPR operator==(const Rep& r) const {return data_ == r.data_;}
+ bool TEST_CONSTEXPR operator==(int i) const {return data_ == i;}
+ bool TEST_CONSTEXPR operator==(const Rep& r) const {return data_ == r.data_;}
Rep& operator*=(Rep x) {data_ *= x.data_; return *this;}
Rep& operator/=(Rep x) {data_ /= x.data_; return *this;}
diff --git a/test/std/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp
index 7d7e82ac5e23..ae5423ef1161 100644
--- a/test/std/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp
@@ -19,6 +19,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class FromDuration, class ToDuration>
void
test(const FromDuration& df, const ToDuration& d)
@@ -35,7 +37,7 @@ test(const FromDuration& df, const ToDuration& d)
}
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
template<class FromDuration, long long From, class ToDuration, long long To>
void test_constexpr ()
@@ -65,7 +67,7 @@ int main()
std::chrono::duration<double, std::ratio<3600> >(7265./3600));
test(std::chrono::duration<int, std::ratio<2, 3> >(9),
std::chrono::duration<int, std::ratio<3, 5> >(10));
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
test_constexpr<std::chrono::milliseconds, 7265000, std::chrono::hours, 2> ();
test_constexpr<std::chrono::milliseconds, 7265000, std::chrono::minutes,121> ();
diff --git a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp
index a37bb266a0a9..a6f7cc0b89b2 100644
--- a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp
@@ -22,6 +22,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -55,7 +57,7 @@ int main()
assert( (t1 != t2));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr T1 t1(Duration1(3));
constexpr T1 t2(Duration1(3));
diff --git a/test/std/utilities/time/time.point/time.point.comparisons/op_less.pass.cpp b/test/std/utilities/time/time.point/time.point.comparisons/op_less.pass.cpp
index 9d94400ed3d1..d7adf29f2ef8 100644
--- a/test/std/utilities/time/time.point/time.point.comparisons/op_less.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.comparisons/op_less.pass.cpp
@@ -30,6 +30,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -71,7 +73,7 @@ int main()
assert(!(t1 >= t2));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr T1 t1(Duration1(3));
constexpr T1 t2(Duration1(3));
diff --git a/test/std/utilities/time/time.point/time.point.cons/convert.pass.cpp b/test/std/utilities/time/time.point/time.point.cons/convert.pass.cpp
index 6cd7dcb7d2f4..33e349fe8941 100644
--- a/test/std/utilities/time/time.point/time.point.cons/convert.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.cons/convert.pass.cpp
@@ -17,6 +17,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -27,7 +29,7 @@ int main()
std::chrono::time_point<Clock, Duration1> t1 = t2;
assert(t1.time_since_epoch() == Duration1(3000));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration2> t2(Duration2(3));
constexpr std::chrono::time_point<Clock, Duration1> t1 = t2;
diff --git a/test/std/utilities/time/time.point/time.point.cons/default.pass.cpp b/test/std/utilities/time/time.point/time.point.cons/default.pass.cpp
index 01f0bc169933..120fd3fb4e9f 100644
--- a/test/std/utilities/time/time.point/time.point.cons/default.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.cons/default.pass.cpp
@@ -16,6 +16,7 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
#include "../../rep.h"
int main()
@@ -26,7 +27,7 @@ int main()
std::chrono::time_point<Clock, Duration> t;
assert(t.time_since_epoch() == Duration::zero());
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration> t;
static_assert(t.time_since_epoch() == Duration::zero(), "");
diff --git a/test/std/utilities/time/time.point/time.point.cons/duration.pass.cpp b/test/std/utilities/time/time.point/time.point.cons/duration.pass.cpp
index 9d53d86dea3b..1b96902aba3b 100644
--- a/test/std/utilities/time/time.point/time.point.cons/duration.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.cons/duration.pass.cpp
@@ -16,6 +16,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -28,7 +30,7 @@ int main()
std::chrono::time_point<Clock, Duration> t(std::chrono::seconds(3));
assert(t.time_since_epoch() == Duration(3000));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration> t(Duration(3));
static_assert(t.time_since_epoch() == Duration(3), "");
diff --git a/test/std/utilities/time/time.point/time.point.nonmember/op_+.pass.cpp b/test/std/utilities/time/time.point/time.point.nonmember/op_+.pass.cpp
index 7a8fa6dcf14f..19f5cbcd9f41 100644
--- a/test/std/utilities/time/time.point/time.point.nonmember/op_+.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.nonmember/op_+.pass.cpp
@@ -22,6 +22,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -34,7 +36,7 @@ int main()
t2 = Duration2(6) + t1;
assert(t2.time_since_epoch() == Duration2(3006));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration1> t1(Duration1(3));
constexpr std::chrono::time_point<Clock, Duration2> t2 = t1 + Duration2(5);
diff --git a/test/std/utilities/time/time.point/time.point.nonmember/op_-duration.pass.cpp b/test/std/utilities/time/time.point/time.point.nonmember/op_-duration.pass.cpp
index 342d27b5aebd..978f09d66bb2 100644
--- a/test/std/utilities/time/time.point/time.point.nonmember/op_-duration.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.nonmember/op_-duration.pass.cpp
@@ -18,6 +18,19 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
+template <class D>
+void test2739() // LWG2739
+{
+ typedef std::chrono::time_point<std::chrono::system_clock> TimePoint;
+ typedef std::chrono::duration<D> Dur;
+ const Dur d(5);
+ TimePoint t0 = std::chrono::system_clock::from_time_t(200);
+ TimePoint t1 = t0 - d;
+ assert(t1 < t0);
+}
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -28,11 +41,13 @@ int main()
std::chrono::time_point<Clock, Duration2> t2 = t1 - Duration2(5);
assert(t2.time_since_epoch() == Duration2(2995));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration1> t1(Duration1(3));
constexpr std::chrono::time_point<Clock, Duration2> t2 = t1 - Duration2(5);
static_assert(t2.time_since_epoch() == Duration2(2995), "");
}
#endif
+ test2739<int32_t>();
+ test2739<uint32_t>();
}
diff --git a/test/std/utilities/time/time.point/time.point.nonmember/op_-time_point.pass.cpp b/test/std/utilities/time/time.point/time.point.nonmember/op_-time_point.pass.cpp
index 5267f07e1b86..fcef3f249733 100644
--- a/test/std/utilities/time/time.point/time.point.nonmember/op_-time_point.pass.cpp
+++ b/test/std/utilities/time/time.point/time.point.nonmember/op_-time_point.pass.cpp
@@ -18,6 +18,8 @@
#include <chrono>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
typedef std::chrono::system_clock Clock;
@@ -28,7 +30,7 @@ int main()
std::chrono::time_point<Clock, Duration2> t2(Duration2(5));
assert((t1 - t2) == Duration2(2995));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::chrono::time_point<Clock, Duration1> t1(Duration1(3));
constexpr std::chrono::time_point<Clock, Duration2> t2(Duration2(5));
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp
index 2e821945d09a..4c15499f5c1d 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp
@@ -166,7 +166,6 @@ void check_apply_quals_and_types(Tuple&& t) {
void test_call_quals_and_arg_types()
{
- TrackedCallable obj;
using Tup = std::tuple<int, int const&, unsigned&&>;
const int x = 42;
unsigned y = 101;
@@ -199,7 +198,7 @@ void test_noexcept()
// test that the functions noexcept-ness is propagated
using Tup = std::tuple<int, const char*, long>;
Tup t;
- ASSERT_NOEXCEPT(std::apply(nec, t));
+ LIBCPP_ASSERT_NOEXCEPT(std::apply(nec, t));
ASSERT_NOT_NOEXCEPT(std::apply(tc, t));
}
{
@@ -207,7 +206,7 @@ void test_noexcept()
using Tup = std::tuple<NothrowMoveable, int>;
Tup t;
ASSERT_NOT_NOEXCEPT(std::apply(nec, t));
- ASSERT_NOEXCEPT(std::apply(nec, std::move(t)));
+ LIBCPP_ASSERT_NOEXCEPT(std::apply(nec, std::move(t)));
}
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
index 143ae195e6f4..eee1dd88253c 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
@@ -175,14 +175,14 @@ void test_noexcept() {
Tuple tup; ((void)tup);
Tuple const& ctup = tup; ((void)ctup);
ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup));
- ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup)));
+ LIBCPP_ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup)));
}
{
using Tuple = std::pair<int, NothrowMoveable>;
Tuple tup; ((void)tup);
Tuple const& ctup = tup; ((void)ctup);
ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup));
- ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup)));
+ LIBCPP_ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup)));
}
{
using Tuple = std::tuple<int, int, int>;
@@ -192,7 +192,7 @@ void test_noexcept() {
{
using Tuple = std::tuple<long, long, long>;
Tuple tup; ((void)tup);
- ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup));
+ LIBCPP_ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup));
}
{
using Tuple = std::array<int, 3>;
@@ -202,7 +202,7 @@ void test_noexcept() {
{
using Tuple = std::array<long, 3>;
Tuple tup; ((void)tup);
- ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup));
+ LIBCPP_ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup));
}
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
index a3d14487b47d..a66fba22d919 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
@@ -23,9 +23,9 @@
int main()
{
{
- typedef std::pair<double, char> T0;
- typedef std::tuple<int, short> T1;
- T0 t0(2.5, 'a');
+ typedef std::pair<long, char> T0;
+ typedef std::tuple<long long, short> T1;
+ T0 t0(2, 'a');
T1 t1;
t1 = t0;
assert(std::get<0>(t1) == 2);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
index 91892efaf139..85dcee893a07 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
@@ -36,26 +36,26 @@ struct D
int main()
{
{
- typedef std::tuple<double> T0;
- typedef std::tuple<int> T1;
- T0 t0(2.5);
+ typedef std::tuple<long> T0;
+ typedef std::tuple<long long> T1;
+ T0 t0(2);
T1 t1;
t1 = t0;
assert(std::get<0>(t1) == 2);
}
{
- typedef std::tuple<double, char> T0;
- typedef std::tuple<int, int> T1;
- T0 t0(2.5, 'a');
+ typedef std::tuple<long, char> T0;
+ typedef std::tuple<long long, int> T1;
+ T0 t0(2, 'a');
T1 t1;
t1 = t0;
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
}
{
- typedef std::tuple<double, char, D> T0;
- typedef std::tuple<int, int, B> T1;
- T0 t0(2.5, 'a', D(3));
+ typedef std::tuple<long, char, D> T0;
+ typedef std::tuple<long long, int, B> T1;
+ T0 t0(2, 'a', D(3));
T1 t1;
t1 = t0;
assert(std::get<0>(t1) == 2);
@@ -65,10 +65,10 @@ int main()
{
D d(3);
D d2(2);
- typedef std::tuple<double, char, D&> T0;
- typedef std::tuple<int, int, B&> T1;
- T0 t0(2.5, 'a', d2);
- T1 t1(1.5, 'b', d);
+ typedef std::tuple<long, char, D&> T0;
+ typedef std::tuple<long long, int, B&> T1;
+ T0 t0(2, 'a', d2);
+ T1 t1(1, 'b', d);
t1 = t0;
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
index afd3e0fdb8e3..1a32acd55cff 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
@@ -39,7 +39,7 @@ struct D
struct E {
E() = default;
- E& operator=(int val) {
+ E& operator=(int) {
return *this;
}
};
@@ -47,26 +47,26 @@ struct E {
int main()
{
{
- typedef std::tuple<double> T0;
- typedef std::tuple<int> T1;
- T0 t0(2.5);
+ typedef std::tuple<long> T0;
+ typedef std::tuple<long long> T1;
+ T0 t0(2);
T1 t1;
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
}
{
- typedef std::tuple<double, char> T0;
- typedef std::tuple<int, int> T1;
- T0 t0(2.5, 'a');
+ typedef std::tuple<long, char> T0;
+ typedef std::tuple<long long, int> T1;
+ T0 t0(2, 'a');
T1 t1;
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
}
{
- typedef std::tuple<double, char, D> T0;
- typedef std::tuple<int, int, B> T1;
- T0 t0(2.5, 'a', D(3));
+ typedef std::tuple<long, char, D> T0;
+ typedef std::tuple<long long, int, B> T1;
+ T0 t0(2, 'a', D(3));
T1 t1;
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
@@ -76,19 +76,19 @@ int main()
{
D d(3);
D d2(2);
- typedef std::tuple<double, char, D&> T0;
- typedef std::tuple<int, int, B&> T1;
- T0 t0(2.5, 'a', d2);
- T1 t1(1.5, 'b', d);
+ typedef std::tuple<long, char, D&> T0;
+ typedef std::tuple<long long, int, B&> T1;
+ T0 t0(2, 'a', d2);
+ T1 t1(1, 'b', d);
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
assert(std::get<2>(t1).id_ == 2);
}
{
- typedef std::tuple<double, char, std::unique_ptr<D>> T0;
- typedef std::tuple<int, int, std::unique_ptr<B>> T1;
- T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ typedef std::tuple<long, char, std::unique_ptr<D>> T0;
+ typedef std::tuple<long long, int, std::unique_ptr<B>> T1;
+ T0 t0(2, 'a', std::unique_ptr<D>(new D(3)));
T1 t1;
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
index d5d020779726..edb235a41919 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
@@ -16,9 +16,26 @@
// UNSUPPORTED: c++98, c++03
#include <tuple>
+#include <memory>
#include <string>
#include <cassert>
+#include "test_macros.h"
+
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable &&) = delete;
+};
+static_assert(std::is_copy_assignable<CopyAssignable>::value, "");
+struct MoveAssignable {
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
int main()
{
{
@@ -51,4 +68,37 @@ int main()
assert(std::get<1>(t) == 'a');
assert(std::get<2>(t) == "some text");
}
+ {
+ // test reference assignment.
+ using T = std::tuple<int&, int&&>;
+ int x = 42;
+ int y = 100;
+ int x2 = -1;
+ int y2 = 500;
+ T t(x, std::move(y));
+ T t2(x2, std::move(y2));
+ t = t2;
+ assert(std::get<0>(t) == x2);
+ assert(&std::get<0>(t) == &x);
+ assert(std::get<1>(t) == y2);
+ assert(&std::get<1>(t) == &y);
+ }
+ {
+ // test that the implicitly generated copy assignment operator
+ // is properly deleted
+ using T = std::tuple<std::unique_ptr<int>>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, NonAssignable>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, CopyAssignable>;
+ static_assert(std::is_copy_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, MoveAssignable>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ }
}
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 fc5e41ad569d..210f14be318a 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
@@ -21,6 +21,33 @@
#include "MoveOnly.h"
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+static_assert(std::is_copy_assignable<CopyAssignable>::value, "");
+struct MoveAssignable {
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+
+struct CountAssign {
+ static int copied;
+ static int moved;
+ static void reset() { copied = moved = 0; }
+ CountAssign() = default;
+ CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
+ CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
+};
+int CountAssign::copied = 0;
+int CountAssign::moved = 0;
+
+
int main()
{
{
@@ -53,4 +80,46 @@ int main()
assert(std::get<1>(t) == 1);
assert(std::get<2>(t) == 2);
}
+ {
+ // test reference assignment.
+ using T = std::tuple<int&, int&&>;
+ int x = 42;
+ int y = 100;
+ int x2 = -1;
+ int y2 = 500;
+ T t(x, std::move(y));
+ T t2(x2, std::move(y2));
+ t = std::move(t2);
+ assert(std::get<0>(t) == x2);
+ assert(&std::get<0>(t) == &x);
+ assert(std::get<1>(t) == y2);
+ assert(&std::get<1>(t) == &y);
+ }
+ {
+ // test that the implicitly generated move assignment operator
+ // is properly deleted
+ using T = std::tuple<std::unique_ptr<int>>;
+ static_assert(std::is_move_assignable<T>::value, "");
+ static_assert(!std::is_copy_assignable<T>::value, "");
+
+ }
+ {
+ using T = std::tuple<int, NonAssignable>;
+ static_assert(!std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, MoveAssignable>;
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+ {
+ // The move should decay to a copy.
+ CountAssign::reset();
+ using T = std::tuple<CountAssign, CopyAssignable>;
+ static_assert(std::is_move_assignable<T>::value, "");
+ T t1;
+ T t2;
+ t1 = std::move(t2);
+ assert(CountAssign::copied == 1);
+ assert(CountAssign::moved == 0);
+ }
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp
index 812e6329bb3e..27656a675982 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp
@@ -39,9 +39,9 @@ struct D
int main()
{
{
- typedef std::pair<double, std::unique_ptr<D>> T0;
- typedef std::tuple<int, std::unique_ptr<B>> T1;
- T0 t0(2.5, std::unique_ptr<D>(new D(3)));
+ typedef std::pair<long, std::unique_ptr<D>> T0;
+ typedef std::tuple<long long, std::unique_ptr<B>> T1;
+ T0 t0(2, std::unique_ptr<D>(new D(3)));
T1 t1;
t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp
index ed3cafadbf08..a5b3d4415e38 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp
@@ -91,6 +91,8 @@ int main() {
}
{
std::tuple<A&&> t(std::forward_as_tuple(A{}));
+ ((void)t);
std::tuple<ExplicitA&&> t2(std::forward_as_tuple(ExplicitA{}));
+ ((void)t2);
}
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp
new file mode 100644
index 000000000000..dd9b832423a6
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <tuple>
+
+// template <class TupleLike> tuple(TupleLike&&); // libc++ extension
+
+// See llvm.org/PR31384
+#include <tuple>
+#include <cassert>
+
+int count = 0;
+
+struct Explicit {
+ Explicit() = default;
+ explicit Explicit(int) {}
+};
+
+struct Implicit {
+ Implicit() = default;
+ Implicit(int) {}
+};
+
+template<class T>
+struct Derived : std::tuple<T> {
+ using std::tuple<T>::tuple;
+ template<class U>
+ operator std::tuple<U>() && { ++count; return {}; }
+};
+
+
+template<class T>
+struct ExplicitDerived : std::tuple<T> {
+ using std::tuple<T>::tuple;
+ template<class U>
+ explicit operator std::tuple<U>() && { ++count; return {}; }
+};
+
+int main() {
+ {
+ std::tuple<Explicit> foo = Derived<int>{42}; ((void)foo);
+ assert(count == 1);
+ std::tuple<Explicit> bar(Derived<int>{42}); ((void)bar);
+ assert(count == 2);
+ }
+ count = 0;
+ {
+ std::tuple<Implicit> foo = Derived<int>{42}; ((void)foo);
+ assert(count == 1);
+ std::tuple<Implicit> bar(Derived<int>{42}); ((void)bar);
+ assert(count == 2);
+ }
+ count = 0;
+ {
+ static_assert(!std::is_convertible<
+ ExplicitDerived<int>, std::tuple<Explicit>>::value, "");
+ std::tuple<Explicit> bar(ExplicitDerived<int>{42}); ((void)bar);
+ assert(count == 1);
+ }
+ count = 0;
+ {
+ // FIXME: Libc++ incorrectly rejects this code.
+#ifndef _LIBCPP_VERSION
+ std::tuple<Implicit> foo = ExplicitDerived<int>{42}; ((void)foo);
+ static_assert(std::is_convertible<
+ ExplicitDerived<int>, std::tuple<Implicit>>::value,
+ "correct STLs accept this");
+#else
+ static_assert(!std::is_convertible<
+ ExplicitDerived<int>, std::tuple<Implicit>>::value,
+ "libc++ incorrectly rejects this");
+#endif
+ assert(count == 0);
+ std::tuple<Implicit> bar(ExplicitDerived<int>{42}); ((void)bar);
+ assert(count == 1);
+ }
+ count = 0;
+
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
index 6ab303c735be..06284df56642 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
@@ -20,9 +20,11 @@
#include <cassert>
#include <type_traits>
+#include "test_macros.h"
+#include "test_convertible.hpp"
#include "MoveOnly.h"
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
struct Empty {};
struct A
@@ -123,17 +125,23 @@ int main()
// extensions
#ifdef _LIBCPP_VERSION
{
- std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0),
- MoveOnly(1));
+ using E = MoveOnly;
+ using Tup = std::tuple<E, E, E>;
+ // Test that the reduced arity initialization extension is only
+ // allowed on the explicit constructor.
+ static_assert(test_convertible<Tup, E, E, E>(), "");
+
+ Tup t(E(0), E(1));
+ static_assert(!test_convertible<Tup, E, E>(), "");
assert(std::get<0>(t) == 0);
assert(std::get<1>(t) == 1);
assert(std::get<2>(t) == MoveOnly());
- }
- {
- std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0));
+
+ Tup t2(E(0));
+ static_assert(!test_convertible<Tup, E>(), "");
assert(std::get<0>(t) == 0);
- assert(std::get<1>(t) == MoveOnly());
- assert(std::get<2>(t) == MoveOnly());
+ assert(std::get<1>(t) == E());
+ assert(std::get<2>(t) == E());
}
#endif
#if TEST_STD_VER > 11
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_pair.pass.cpp
index c5941618180d..1d0c7b49aaaa 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_pair.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_pair.pass.cpp
@@ -27,8 +27,8 @@
int main()
{
{
- typedef std::pair<double, int> T0;
- typedef std::tuple<int, double> T1;
+ typedef std::pair<long, int> T0;
+ typedef std::tuple<long long, double> T1;
T0 t0(2, 3);
T1 t1(std::allocator_arg, A1<int>(5), t0);
assert(std::get<0>(t1) == 2);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp
index 36d9f32879cb..153cd2b3d7ce 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp
@@ -37,9 +37,9 @@ struct Implicit {
int main()
{
{
- typedef std::tuple<double> T0;
- typedef std::tuple<int> T1;
- T0 t0(2.5);
+ typedef std::tuple<long> T0;
+ typedef std::tuple<long long> T1;
+ T0 t0(2);
T1 t1(std::allocator_arg, A1<int>(), t0);
assert(std::get<0>(t1) == 2);
}
@@ -65,9 +65,9 @@ int main()
assert(std::get<1>(t1) == 3);
}
{
- typedef std::tuple<double, int, int> T0;
- typedef std::tuple<int, alloc_first, alloc_last> T1;
- T0 t0(1.5, 2, 3);
+ typedef std::tuple<long, int, int> T0;
+ typedef std::tuple<long long, alloc_first, alloc_last> T1;
+ T0 t0(1, 2, 3);
alloc_first::allocator_constructed = false;
alloc_last::allocator_constructed = false;
T1 t1(std::allocator_arg, A1<int>(5), t0);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
index 367f19e5d8dd..0da132fcfc26 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
@@ -19,6 +19,7 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
template <class ...>
struct never {
@@ -81,12 +82,13 @@ int main()
{
// check that the literal '0' can implicitly initialize a stored pointer.
std::tuple<int*> t = 0;
+ assert(std::get<0>(t) == nullptr);
}
{
std::tuple<int> t(2);
assert(std::get<0>(t) == 2);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::tuple<int> t(2);
static_assert(std::get<0>(t) == 2, "");
@@ -101,7 +103,7 @@ int main()
assert(std::get<0>(t) == 2);
assert(std::get<1>(t) == nullptr);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::tuple<int, char*> t(2, nullptr);
static_assert(std::get<0>(t) == 2, "");
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp
index d6d489fd0ea4..bed161a3dcef 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp
@@ -19,23 +19,25 @@
#include <utility>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
- typedef std::pair<double, char> T0;
- typedef std::tuple<int, short> T1;
- T0 t0(2.5, 'a');
+ typedef std::pair<long, char> T0;
+ typedef std::tuple<long long, short> T1;
+ T0 t0(2, 'a');
T1 t1 = t0;
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == short('a'));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
- typedef std::pair<double, char> P0;
- typedef std::tuple<int, short> T1;
- constexpr P0 p0(2.5, 'a');
+ typedef std::pair<long, char> P0;
+ typedef std::tuple<long long, short> T1;
+ constexpr P0 p0(2, 'a');
constexpr T1 t1 = p0;
- static_assert(std::get<0>(t1) != std::get<0>(p0), "");
+ static_assert(std::get<0>(t1) == std::get<0>(p0), "");
static_assert(std::get<1>(t1) == std::get<1>(p0), "");
static_assert(std::get<0>(t1) == 2, "");
static_assert(std::get<1>(t1) == short('a'), "");
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp
index b7fa2e3a03cc..4609b042556b 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp
@@ -20,6 +20,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
struct Explicit {
int value;
explicit Explicit(int x) : value(x) {}
@@ -43,7 +45,7 @@ struct D
explicit D(int i) : B(i) {}
};
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
struct A
{
@@ -66,17 +68,17 @@ struct C
int main()
{
{
- typedef std::tuple<double> T0;
- typedef std::tuple<int> T1;
- T0 t0(2.5);
+ typedef std::tuple<long> T0;
+ typedef std::tuple<long long> T1;
+ T0 t0(2);
T1 t1 = t0;
assert(std::get<0>(t1) == 2);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
- typedef std::tuple<double> T0;
+ typedef std::tuple<int> T0;
typedef std::tuple<A> T1;
- constexpr T0 t0(2.5);
+ constexpr T0 t0(2);
constexpr T1 t1 = t0;
static_assert(std::get<0>(t1) == 2, "");
}
@@ -89,17 +91,17 @@ int main()
}
#endif
{
- typedef std::tuple<double, char> T0;
- typedef std::tuple<int, int> T1;
- T0 t0(2.5, 'a');
+ typedef std::tuple<long, char> T0;
+ typedef std::tuple<long long, int> T1;
+ T0 t0(2, 'a');
T1 t1 = t0;
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
}
{
- typedef std::tuple<double, char, D> T0;
- typedef std::tuple<int, int, B> T1;
- T0 t0(2.5, 'a', D(3));
+ typedef std::tuple<long, char, D> T0;
+ typedef std::tuple<long long, int, B> T1;
+ T0 t0(2, 'a', D(3));
T1 t1 = t0;
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
@@ -107,9 +109,9 @@ int main()
}
{
D d(3);
- typedef std::tuple<double, char, D&> T0;
- typedef std::tuple<int, int, B&> T1;
- T0 t0(2.5, 'a', d);
+ typedef std::tuple<long, char, D&> T0;
+ typedef std::tuple<long long, int, B&> T1;
+ T0 t0(2, 'a', d);
T1 t1 = t0;
d.id_ = 2;
assert(std::get<0>(t1) == 2);
@@ -117,9 +119,9 @@ int main()
assert(std::get<2>(t1).id_ == 2);
}
{
- typedef std::tuple<double, char, int> T0;
- typedef std::tuple<int, int, B> T1;
- T0 t0(2.5, 'a', 3);
+ typedef std::tuple<long, char, int> T0;
+ typedef std::tuple<long long, int, B> T1;
+ T0 t0(2, 'a', 3);
T1 t1(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
index 8423f5d0145f..2af86fdd0868 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
@@ -48,24 +48,24 @@ struct D
int main()
{
{
- typedef std::tuple<double> T0;
- typedef std::tuple<int> T1;
- T0 t0(2.5);
+ typedef std::tuple<long> T0;
+ typedef std::tuple<long long> T1;
+ T0 t0(2);
T1 t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
}
{
- typedef std::tuple<double, char> T0;
- typedef std::tuple<int, int> T1;
- T0 t0(2.5, 'a');
+ typedef std::tuple<long, char> T0;
+ typedef std::tuple<long long, int> T1;
+ T0 t0(2, 'a');
T1 t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
}
{
- typedef std::tuple<double, char, D> T0;
- typedef std::tuple<int, int, B> T1;
- T0 t0(2.5, 'a', D(3));
+ typedef std::tuple<long, char, D> T0;
+ typedef std::tuple<long long, int, B> T1;
+ T0 t0(2, 'a', D(3));
T1 t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
@@ -73,9 +73,9 @@ int main()
}
{
D d(3);
- typedef std::tuple<double, char, D&> T0;
- typedef std::tuple<int, int, B&> T1;
- T0 t0(2.5, 'a', d);
+ typedef std::tuple<long, char, D&> T0;
+ typedef std::tuple<long long, int, B&> T1;
+ T0 t0(2, 'a', d);
T1 t1 = std::move(t0);
d.id_ = 2;
assert(std::get<0>(t1) == 2);
@@ -83,9 +83,9 @@ int main()
assert(std::get<2>(t1).id_ == 2);
}
{
- typedef std::tuple<double, char, std::unique_ptr<D>> T0;
- typedef std::tuple<int, int, std::unique_ptr<B>> T1;
- T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ typedef std::tuple<long, char, std::unique_ptr<D>> T0;
+ typedef std::tuple<long long, int, std::unique_ptr<B>> T1;
+ T0 t0(2, 'a', std::unique_ptr<D>(new D(3)));
T1 t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a'));
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.pass.cpp
index 783c9d1f06a8..1137df2918dd 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.pass.cpp
@@ -19,6 +19,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
struct Empty {};
int main()
@@ -50,7 +52,7 @@ int main()
assert(std::get<1>(t) == 'a');
assert(std::get<2>(t) == "some text");
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef std::tuple<int> T;
constexpr T t0(2);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/dtor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/dtor.pass.cpp
new file mode 100644
index 000000000000..fbcda44e4065
--- /dev/null
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/dtor.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
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// ~tuple();
+
+#include <tuple>
+#include <string>
+#include <cassert>
+#include <type_traits>
+
+int main()
+{
+ static_assert(std::is_trivially_destructible<
+ std::tuple<> >::value, "");
+ static_assert(std::is_trivially_destructible<
+ std::tuple<void*> >::value, "");
+ static_assert(std::is_trivially_destructible<
+ std::tuple<int, float> >::value, "");
+ static_assert(!std::is_trivially_destructible<
+ std::tuple<std::string> >::value, "");
+ static_assert(!std::is_trivially_destructible<
+ std::tuple<int, std::string> >::value, "");
+}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp
index 0c93673532bb..1cc13cf58ba8 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp
@@ -29,7 +29,7 @@ struct ConstructsWithTupleLeaf
ConstructsWithTupleLeaf(ConstructsWithTupleLeaf &&) {}
template <class T>
- ConstructsWithTupleLeaf(T t) {
+ ConstructsWithTupleLeaf(T) {
static_assert(!std::is_same<T, T>::value,
"Constructor instantiated for type other than int");
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move_pair.pass.cpp
index 2dfbaff6cc1a..13558f3fbe17 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move_pair.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move_pair.pass.cpp
@@ -38,9 +38,9 @@ struct D
int main()
{
{
- typedef std::pair<double, std::unique_ptr<D>> T0;
- typedef std::tuple<int, std::unique_ptr<B>> T1;
- T0 t0(2.5, std::unique_ptr<D>(new D(3)));
+ typedef std::pair<long, std::unique_ptr<D>> T0;
+ typedef std::tuple<long long, std::unique_ptr<B>> T1;
+ T0 t0(2, std::unique_ptr<D>(new D(3)));
T1 t1 = std::move(t0);
assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1)->id_ == 3);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp
index 2dbe81513a1a..1099e3579687 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp
@@ -18,6 +18,8 @@
#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
template <class Tuple>
void
test0(const Tuple&)
@@ -54,7 +56,7 @@ test2a(const Tuple& t)
assert(std::get<1>(t) == 'a');
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
template <class Tuple>
constexpr int
test3(const Tuple&)
@@ -79,7 +81,7 @@ int main()
double i = 2.5;
char c = 'a';
test2a(std::forward_as_tuple(i, c));
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert ( test3 (std::forward_as_tuple(i, c)) == 2, "" );
#endif
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
index f27e8a09fb97..2c38bf7d230c 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
@@ -20,6 +20,8 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
@@ -40,7 +42,7 @@ int main()
assert(i == 0);
assert(j == 0);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr auto t1 = std::make_tuple(0, 1, 3.14);
constexpr int i1 = std::get<1>(t1);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
index 52ecd249402f..c4c3c242d8f8 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
@@ -20,6 +20,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
@@ -29,7 +31,7 @@ int main()
assert(i == 42);
assert(s == "C++");
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
static constexpr int i = 42;
static constexpr double f = 1.1;
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
index 770edcaca5e1..18095f7e3033 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "MoveOnly.h"
int main()
@@ -48,7 +49,7 @@ int main()
assert(std::get<0>(t) == 1);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
constexpr std::tuple<> t = std::tuple_cat();
((void)t); // Prevent unused warning
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp
index 002ad148ad6d..f014916742ad 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp
@@ -21,6 +21,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
struct Empty {};
int main()
@@ -36,7 +38,7 @@ int main()
assert(std::get<0>(t) == "high");
assert(std::get<1>(t) == 5);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef std::tuple<double, int> T;
constexpr T t(2.718, 5);
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp
index 58df2df7679a..9c2d992b8e49 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const_rv.fail.cpp
@@ -19,7 +19,7 @@
#include <tuple>
-template <class T> void cref(T const&) {};
+template <class T> void cref(T const&) {}
template <class T> void cref(T const&&) = delete;
std::tuple<int> const tup4() { return std::make_tuple(4); }
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp
index 86d1191db556..fc53412899fb 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp
@@ -71,7 +71,7 @@ int main()
assert(std::get<2>(t) == 4);
assert(d == 2.5);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{ // get on an rvalue tuple
static_assert ( std::get<0> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 0, "" );
static_assert ( std::get<1> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 1, "" );
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.pass.cpp
index 42e4fab88ffa..5beedbe9d157 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.pass.cpp
@@ -23,6 +23,8 @@
#include <tuple>
#include <type_traits>
+#include "test_macros.h"
+
template <class T, std::size_t N, class U>
void test()
{
@@ -30,7 +32,7 @@ void test()
static_assert((std::is_same<typename std::tuple_element<N, const T>::type, const U>::value), "");
static_assert((std::is_same<typename std::tuple_element<N, volatile T>::type, volatile U>::value), "");
static_assert((std::is_same<typename std::tuple_element<N, const volatile T>::type, const volatile U>::value), "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert((std::is_same<typename std::tuple_element_t<N, T>, U>::value), "");
static_assert((std::is_same<typename std::tuple_element_t<N, const T>, const U>::value), "");
static_assert((std::is_same<typename std::tuple_element_t<N, volatile T>, volatile U>::value), "");
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp
index 3f132e47b626..50c6f17efbef 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp
@@ -21,7 +21,7 @@
int main()
{
- (void)std::tuple_size<std::tuple<> &>::value; // expected-error {{implicit instantiation of undefined template}}
- (void)std::tuple_size<int>::value; // expected-error {{implicit instantiation of undefined template}}
- (void)std::tuple_size<std::tuple<>*>::value; // expected-error {{implicit instantiation of undefined template}}
+ (void)std::tuple_size<std::tuple<> &>::value; // expected-error {{no member named 'value'}}
+ (void)std::tuple_size<int>::value; // expected-error {{no member named 'value'}}
+ (void)std::tuple_size<std::tuple<>*>::value; // expected-error {{no member named 'value'}}
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
index 49b4215a1956..40214f632e75 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp
@@ -18,19 +18,36 @@
// UNSUPPORTED: c++98, c++03
#include <tuple>
+#include <utility>
+#include <array>
#include <type_traits>
+template <class T, class = decltype(std::tuple_size<T>::value)>
+constexpr bool has_value(int) { return true; }
+template <class> constexpr bool has_value(long) { return false; }
+template <class T> constexpr bool has_value() { return has_value<T>(0); }
+
+
template <class T, std::size_t N>
void test()
{
+ static_assert(has_value<T>(), "");
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
std::tuple_size<T> >::value), "");
+ static_assert(has_value<const T>(), "");
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
std::tuple_size<const T> >::value), "");
+ static_assert(has_value<volatile T>(), "");
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
std::tuple_size<volatile T> >::value), "");
+
+ static_assert(has_value<const volatile T>(), "");
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
std::tuple_size<const volatile T> >::value), "");
+ {
+ static_assert(!has_value<T &>(), "");
+ static_assert(!has_value<T *>(), "");
+ }
}
int main()
@@ -39,4 +56,13 @@ int main()
test<std::tuple<int>, 1>();
test<std::tuple<char, int>, 2>();
test<std::tuple<char, char*, int>, 3>();
+ test<std::pair<int, void*>, 2>();
+ test<std::array<int, 42>, 42>();
+ {
+ static_assert(!has_value<void>(), "");
+ static_assert(!has_value<void*>(), "");
+ static_assert(!has_value<int>(), "");
+ static_assert(!has_value<std::pair<int, int>*>(), "");
+ static_assert(!has_value<std::array<int, 42>&>(), "");
+ }
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp
index 957a683b47f8..700dd95c959c 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp
@@ -22,5 +22,5 @@ int main()
(void)std::tuple_size_v<std::tuple<> &>; // expected-note {{requested here}}
(void)std::tuple_size_v<int>; // expected-note {{requested here}}
(void)std::tuple_size_v<std::tuple<>*>; // expected-note {{requested here}}
- // expected-error@tuple:* 3 {{implicit instantiation of undefined template}}
+ // expected-error@tuple:* 3 {{no member named 'value'}}
}
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
index e5991df636f8..a802a05da2bc 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp
@@ -21,6 +21,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
@@ -49,104 +51,104 @@ int main()
}
{
typedef std::tuple<int, double> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
- const T2 t2(1, char(2));
+ const T2 t2(1, 2);
assert(t1 == t2);
assert(!(t1 != t2));
}
{
typedef std::tuple<int, double> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
- const T2 t2(1, char(3));
+ const T2 t2(1, 3);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
typedef std::tuple<int, double> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
- const T2 t2(1.1, char(2));
+ const T2 t2(1.1, 2);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
typedef std::tuple<int, double> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
- const T2 t2(1.1, char(3));
+ const T2 t2(1.1, 3);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 2, 3);
assert(t1 == t2);
assert(!(t1 != t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1.1, 2, 3);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 3, 3);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 2, 4);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 3, 2);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1.1, 2, 2);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1.1, 3, 3);
assert(!(t1 == t2));
assert(t1 != t2);
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1.1, 3, 2);
assert(!(t1 == t2));
assert(t1 != t2);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
constexpr T1 t1(1, 2, 3);
constexpr T2 t2(1.1, 3, 2);
static_assert(!(t1 == t2), "");
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
index 34aafb1e1347..f4d764b87ee9 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp
@@ -33,6 +33,8 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
@@ -46,7 +48,7 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char> T1;
+ typedef std::tuple<long> T1;
typedef std::tuple<double> T2;
const T1 t1(1);
const T2 t2(1);
@@ -56,7 +58,7 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char> T1;
+ typedef std::tuple<long> T1;
typedef std::tuple<double> T2;
const T1 t1(1);
const T2 t2(0.9);
@@ -66,7 +68,7 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char> T1;
+ typedef std::tuple<long> T1;
typedef std::tuple<double> T2;
const T1 t1(1);
const T2 t2(1.1);
@@ -76,8 +78,8 @@ int main()
assert(!(t1 >= t2));
}
{
- typedef std::tuple<char, int> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<long, int> T1;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
const T2 t2(1, 2);
assert(!(t1 < t2));
@@ -86,8 +88,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<long, int> T1;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
const T2 t2(0.9, 2);
assert(!(t1 < t2));
@@ -96,8 +98,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<long, int> T1;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
const T2 t2(1.1, 2);
assert( (t1 < t2));
@@ -106,8 +108,8 @@ int main()
assert(!(t1 >= t2));
}
{
- typedef std::tuple<char, int> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<long, int> T1;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
const T2 t2(1, 1);
assert(!(t1 < t2));
@@ -116,8 +118,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int> T1;
- typedef std::tuple<double, char> T2;
+ typedef std::tuple<long, int> T1;
+ typedef std::tuple<double, long> T2;
const T1 t1(1, 2);
const T2 t2(1, 3);
assert( (t1 < t2));
@@ -126,8 +128,8 @@ int main()
assert(!(t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 2, 3);
assert(!(t1 < t2));
@@ -136,8 +138,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(0.9, 2, 3);
assert(!(t1 < t2));
@@ -146,8 +148,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1.1, 2, 3);
assert( (t1 < t2));
@@ -156,8 +158,8 @@ int main()
assert(!(t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 1, 3);
assert(!(t1 < t2));
@@ -166,8 +168,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 3, 3);
assert( (t1 < t2));
@@ -176,8 +178,8 @@ int main()
assert(!(t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 2, 2);
assert(!(t1 < t2));
@@ -186,8 +188,8 @@ int main()
assert( (t1 >= t2));
}
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
const T1 t1(1, 2, 3);
const T2 t2(1, 2, 4);
assert( (t1 < t2));
@@ -195,10 +197,10 @@ int main()
assert(!(t1 > t2));
assert(!(t1 >= t2));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
- typedef std::tuple<char, int, double> T1;
- typedef std::tuple<double, char, int> T2;
+ typedef std::tuple<long, int, double> T1;
+ typedef std::tuple<double, long, int> T2;
constexpr T1 t1(1, 2, 3);
constexpr T2 t2(1, 2, 4);
static_assert( (t1 < t2), "");
diff --git a/test/std/utilities/utility/exchange/exchange.pass.cpp b/test/std/utilities/utility/exchange/exchange.pass.cpp
index 5ef0ac3b09f5..2d01d6c8c8af 100644
--- a/test/std/utilities/utility/exchange/exchange.pass.cpp
+++ b/test/std/utilities/utility/exchange/exchange.pass.cpp
@@ -22,10 +22,10 @@ int main()
int v = 12;
assert ( std::exchange ( v, 23 ) == 12 );
assert ( v == 23 );
- assert ( std::exchange ( v, 67.2 ) == 23 );
+ assert ( std::exchange ( v, static_cast<short>(67) ) == 23 );
assert ( v == 67 );
- assert ((std::exchange<int, float> ( v, {} )) == 67 );
+ assert ((std::exchange<int, short> ( v, {} )) == 67 );
assert ( v == 0 );
}
diff --git a/test/std/utilities/utility/forward/forward.fail.cpp b/test/std/utilities/utility/forward/forward.fail.cpp
new file mode 100644
index 000000000000..a3bb890482ef
--- /dev/null
+++ b/test/std/utilities/utility/forward/forward.fail.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test forward
+
+#include <utility>
+
+#include "test_macros.h"
+
+struct A
+{
+};
+
+A source() {return A();}
+const A csource() {return A();}
+
+int main()
+{
+#if TEST_STD_VER >= 11
+ {
+ std::forward<A&>(source()); // expected-note {{requested here}}
+ // expected-error@type_traits:* 1 {{static_assert failed "can not forward an rvalue as an lvalue"}}
+ }
+#else
+ {
+ std::forward<A&>(source()); // expected-error {{no matching function for call to 'forward'}}
+ }
+#endif
+ {
+ const A ca = A();
+ std::forward<A&>(ca); // expected-error {{no matching function for call to 'forward'}}
+ }
+ {
+ std::forward<A&>(csource()); // expected-error {{no matching function for call to 'forward'}}
+ }
+ {
+ const A ca = A();
+ std::forward<A>(ca); // expected-error {{no matching function for call to 'forward'}}
+ }
+ {
+ std::forward<A>(csource()); // expected-error {{no matching function for call to 'forward'}}
+ }
+ {
+ A a;
+ std::forward(a); // expected-error {{no matching function for call to 'forward'}}
+ }
+}
diff --git a/test/std/utilities/utility/forward/forward.pass.cpp b/test/std/utilities/utility/forward/forward.pass.cpp
index 94575485df04..afff8d627fad 100644
--- a/test/std/utilities/utility/forward/forward.pass.cpp
+++ b/test/std/utilities/utility/forward/forward.pass.cpp
@@ -7,32 +7,40 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// test forward
#include <utility>
+#include <type_traits>
#include <cassert>
+#include "test_macros.h"
+
struct A
{
};
-A source() {return A();}
-const A csource() {return A();}
-
-typedef char one;
-struct two {one _[2];};
-struct four {one _[4];};
-struct eight {one _[8];};
-
-one test(A&);
-two test(const A&);
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-four test(A&&);
-eight test(const A&&);
-
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+A source() noexcept {return A();}
+const A csource() noexcept {return A();}
+
+
+constexpr bool test_constexpr_forward() {
+#if TEST_STD_VER > 11
+ int x = 42;
+ const int cx = 101;
+ return std::forward<int&>(x) == 42
+ && std::forward<int>(x) == 42
+ && std::forward<const int&>(x) == 42
+ && std::forward<const int>(x) == 42
+ && std::forward<int&&>(x) == 42
+ && std::forward<const int&&>(x) == 42
+ && std::forward<const int&>(cx) == 101
+ && std::forward<const int>(cx) == 101;
+#else
+ return true;
+#endif
+}
int main()
{
@@ -42,42 +50,42 @@ int main()
((void)a); // Prevent unused warning
((void)ca); // Prevent unused warning
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- static_assert(sizeof(test(std::forward<A&>(a))) == 1, "");
- static_assert(sizeof(test(std::forward<A>(a))) == 4, "");
- static_assert(sizeof(test(std::forward<A>(source()))) == 4, "");
-
- static_assert(sizeof(test(std::forward<const A&>(a))) == 2, "");
-// static_assert(sizeof(test(std::forward<const A&>(source()))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(a))) == 8, "");
- static_assert(sizeof(test(std::forward<const A>(source()))) == 8, "");
-
- static_assert(sizeof(test(std::forward<const A&>(ca))) == 2, "");
-// static_assert(sizeof(test(std::forward<const A&>(csource()))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(ca))) == 8, "");
- static_assert(sizeof(test(std::forward<const A>(csource()))) == 8, "");
-
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- static_assert(sizeof(test(std::forward<A&>(a))) == 1, "");
- static_assert(sizeof(test(std::forward<A>(a))) == 1, "");
-// static_assert(sizeof(test(std::forward<A>(source()))) == 2, "");
-
- static_assert(sizeof(test(std::forward<const A&>(a))) == 2, "");
- static_assert(sizeof(test(std::forward<const A&>(source()))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(a))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(source()))) == 2, "");
-
- static_assert(sizeof(test(std::forward<const A&>(ca))) == 2, "");
- static_assert(sizeof(test(std::forward<const A&>(csource()))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(ca))) == 2, "");
- static_assert(sizeof(test(std::forward<const A>(csource()))) == 2, "");
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#if _LIBCPP_STD_VER > 11
- constexpr int i1 = std::move(23);
- static_assert(i1 == 23, "" );
+ static_assert(std::is_same<decltype(std::forward<A&>(a)), A&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<A>(a)), A&&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<A>(source())), A&&>::value, "");
+ static_assert(noexcept(std::forward<A&>(a)), "");
+ static_assert(noexcept(std::forward<A>(a)), "");
+ static_assert(noexcept(std::forward<A>(source())), "");
+
+ static_assert(std::is_same<decltype(std::forward<const A&>(a)), const A&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<const A>(a)), const A&&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<const A>(source())), const A&&>::value, "");
+ static_assert(noexcept(std::forward<const A&>(a)), "");
+ static_assert(noexcept(std::forward<const A>(a)), "");
+ static_assert(noexcept(std::forward<const A>(source())), "");
+
+ static_assert(std::is_same<decltype(std::forward<const A&>(ca)), const A&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<const A>(ca)), const A&&>::value, "");
+ static_assert(std::is_same<decltype(std::forward<const A>(csource())), const A&&>::value, "");
+ static_assert(noexcept(std::forward<const A&>(ca)), "");
+ static_assert(noexcept(std::forward<const A>(ca)), "");
+ static_assert(noexcept(std::forward<const A>(csource())), "");
+
+#if TEST_STD_VER > 11
+ {
+ constexpr int i2 = std::forward<int>(42);
+ static_assert(std::forward<int>(42) == 42, "");
+ static_assert(std::forward<const int&>(i2) == 42, "");
+ static_assert(test_constexpr_forward(), "");
+ }
+#endif
+#if TEST_STD_VER == 11 && defined(_LIBCPP_VERSION)
+ // Test that std::forward is constexpr in C++11. This is an extension
+ // provided by both libc++ and libstdc++.
+ {
constexpr int i2 = std::forward<int>(42);
- static_assert(i2 == 42, "" );
+ static_assert(std::forward<int>(42) == 42, "" );
+ static_assert(std::forward<const int&>(i2) == 42, "");
+ }
#endif
}
diff --git a/test/std/utilities/utility/forward/forward5.fail.cpp b/test/std/utilities/utility/forward/forward5.fail.cpp
deleted file mode 100644
index 86c2b5651b90..000000000000
--- a/test/std/utilities/utility/forward/forward5.fail.cpp
+++ /dev/null
@@ -1,25 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test forward
-
-#include <utility>
-
-struct A
-{
-};
-
-A source() {return A();}
-const A csource() {return A();}
-
-int main()
-{
- const A ca = A();
- std::forward<A>(csource()); // error
-}
diff --git a/test/std/utilities/utility/forward/forward_03.pass.cpp b/test/std/utilities/utility/forward/forward_03.pass.cpp
new file mode 100644
index 000000000000..7e141bad94e8
--- /dev/null
+++ b/test/std/utilities/utility/forward/forward_03.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.
+//
+//===----------------------------------------------------------------------===//
+
+// test forward
+
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct A
+{
+};
+
+A source() {return A();}
+const A csource() {return A();}
+
+typedef char one;
+struct two {one _[2];};
+struct four {one _[4];};
+struct eight {one _[8];};
+
+one test(A&);
+two test(const A&);
+
+int main()
+{
+ A a;
+ const A ca = A();
+
+ ((void)a); // Prevent unused warning
+ ((void)ca); // Prevent unused warning
+
+#if TEST_STD_VER < 11
+ static_assert(sizeof(test(std::forward<A&>(a))) == 1, "");
+ static_assert(sizeof(test(std::forward<A>(a))) == 1, "");
+
+ // Libc++'s C++03 implementation of 'forward' cannot accept true non-const
+ // rvalues.
+ // static_assert(sizeof(test(std::forward<A>(source()))) == 2, "");
+
+ static_assert(sizeof(test(std::forward<const A&>(a))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A&>(source()))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A>(a))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A>(source()))) == 2, "");
+
+ static_assert(sizeof(test(std::forward<const A&>(ca))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A&>(csource()))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A>(ca))) == 2, "");
+ static_assert(sizeof(test(std::forward<const A>(csource()))) == 2, "");
+#endif
+}
diff --git a/test/std/utilities/utility/forward/move_only.pass.cpp b/test/std/utilities/utility/forward/move.fail.cpp
index 520bf5e5b6a1..bd2126cbaee4 100644
--- a/test/std/utilities/utility/forward/move_only.pass.cpp
+++ b/test/std/utilities/utility/forward/move.fail.cpp
@@ -7,22 +7,17 @@
//
//===----------------------------------------------------------------------===//
-// test move
-
// UNSUPPORTED: c++98, c++03
+// test move
+
#include <utility>
#include <cassert>
-class move_only
-{
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-public:
- move_only(move_only&&) {}
- move_only& operator=(move_only&&) {return *this;}
-
+struct move_only {
move_only() {}
+ move_only(move_only&&) = default;
+ move_only& operator=(move_only&&) = default;
};
move_only source() {return move_only();}
@@ -32,8 +27,8 @@ void test(move_only) {}
int main()
{
- move_only mo;
+ move_only a;
+ const move_only ca = move_only();
- test(std::move(mo));
- test(source());
+ test(std::move(ca)); // c
}
diff --git a/test/std/utilities/utility/forward/move.pass.cpp b/test/std/utilities/utility/forward/move.pass.cpp
new file mode 100644
index 000000000000..e2edc2a2afad
--- /dev/null
+++ b/test/std/utilities/utility/forward/move.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// test move
+
+// UNSUPPORTED: c++98, c++03
+
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+class move_only
+{
+ move_only(const move_only&);
+ move_only& operator=(const move_only&);
+public:
+ move_only(move_only&&) {}
+ move_only& operator=(move_only&&) {return *this;}
+
+ move_only() {}
+};
+
+move_only source() {return move_only();}
+const move_only csource() {return move_only();}
+
+void test(move_only) {}
+
+int x = 42;
+const int& cx = x;
+
+template <class QualInt>
+QualInt get() noexcept { return static_cast<QualInt>(x); }
+
+
+int copy_ctor = 0;
+int move_ctor = 0;
+
+struct A {
+ A() {}
+ A(const A&) {++copy_ctor;}
+ A(A&&) {++move_ctor;}
+ A& operator=(const A&) = delete;
+};
+
+constexpr bool test_constexpr_move() {
+#if TEST_STD_VER > 11
+ int y = 42;
+ const int cy = y;
+ return std::move(y) == 42
+ && std::move(cy) == 42
+ && std::move(static_cast<int&&>(y)) == 42
+ && std::move(static_cast<int const&&>(y)) == 42;
+#else
+ return true;
+#endif
+}
+
+int main()
+{
+ { // Test return type and noexcept.
+ static_assert(std::is_same<decltype(std::move(x)), int&&>::value, "");
+ static_assert(noexcept(std::move(x)), "");
+ static_assert(std::is_same<decltype(std::move(cx)), const int&&>::value, "");
+ static_assert(noexcept(std::move(cx)), "");
+ static_assert(std::is_same<decltype(std::move(42)), int&&>::value, "");
+ static_assert(noexcept(std::move(42)), "");
+ static_assert(std::is_same<decltype(std::move(get<const int&&>())), const int&&>::value, "");
+ static_assert(noexcept(std::move(get<int const&&>())), "");
+ }
+ { // test copy and move semantics
+ A a;
+ const A ca = A();
+
+ assert(copy_ctor == 0);
+ assert(move_ctor == 0);
+
+ A a2 = a;
+ assert(copy_ctor == 1);
+ assert(move_ctor == 0);
+
+ A a3 = std::move(a);
+ assert(copy_ctor == 1);
+ assert(move_ctor == 1);
+
+ A a4 = ca;
+ assert(copy_ctor == 2);
+ assert(move_ctor == 1);
+
+ A a5 = std::move(ca);
+ assert(copy_ctor == 3);
+ assert(move_ctor == 1);
+ }
+ { // test on a move only type
+ move_only mo;
+ test(std::move(mo));
+ test(source());
+ }
+#if TEST_STD_VER > 11
+ {
+ constexpr int y = 42;
+ static_assert(std::move(y) == 42, "");
+ static_assert(test_constexpr_move(), "");
+ }
+#endif
+#if TEST_STD_VER == 11 && defined(_LIBCPP_VERSION)
+ // Test that std::forward is constexpr in C++11. This is an extension
+ // provided by both libc++ and libstdc++.
+ {
+ constexpr int y = 42;
+ static_assert(std::move(y) == 42, "");
+ }
+#endif
+}
diff --git a/test/std/utilities/utility/forward/move_copy.pass.cpp b/test/std/utilities/utility/forward/move_copy.pass.cpp
deleted file mode 100644
index fa15553f669f..000000000000
--- a/test/std/utilities/utility/forward/move_copy.pass.cpp
+++ /dev/null
@@ -1,61 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test move
-
-// UNSUPPORTED: c++98, c++03
-
-#include <utility>
-#include <cassert>
-
-int copy_ctor = 0;
-int move_ctor = 0;
-
-class A
-{
-public:
-
- A(const A&) {++copy_ctor;}
- A& operator=(const A&);
-
- A(A&&) {++move_ctor;}
- A& operator=(A&&);
-
- A() {}
-};
-
-A source() {return A();}
-const A csource() {return A();}
-
-void test(A) {}
-
-int main()
-{
- A a;
- const A ca = A();
-
- assert(copy_ctor == 0);
- assert(move_ctor == 0);
-
- A a2 = a;
- assert(copy_ctor == 1);
- assert(move_ctor == 0);
-
- A a3 = std::move(a);
- assert(copy_ctor == 1);
- assert(move_ctor == 1);
-
- A a4 = ca;
- assert(copy_ctor == 2);
- assert(move_ctor == 1);
-
- A a5 = std::move(ca);
- assert(copy_ctor == 3);
- assert(move_ctor == 1);
-}
diff --git a/test/std/utilities/utility/forward/move_only1.fail.cpp b/test/std/utilities/utility/forward/move_only1.fail.cpp
deleted file mode 100644
index 5e7623a1bd19..000000000000
--- a/test/std/utilities/utility/forward/move_only1.fail.cpp
+++ /dev/null
@@ -1,52 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test move
-
-#include <utility>
-#include <cassert>
-
-#include <typeinfo>
-#include <stdio.h>
-
-class move_only
-{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&&) {}
- move_only& operator=(move_only&&) {}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- move_only() {}
-};
-
-move_only source() {return move_only();}
-const move_only csource() {return move_only();}
-
-void test(move_only) {}
-
-int main()
-{
- move_only a;
- const move_only ca = move_only();
-
- test(a);
-}
diff --git a/test/std/utilities/utility/forward/move_only2.fail.cpp b/test/std/utilities/utility/forward/move_only2.fail.cpp
deleted file mode 100644
index 2043f3d4bde7..000000000000
--- a/test/std/utilities/utility/forward/move_only2.fail.cpp
+++ /dev/null
@@ -1,52 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test move
-
-#include <utility>
-#include <cassert>
-
-#include <typeinfo>
-#include <stdio.h>
-
-class move_only
-{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&&) {}
- move_only& operator=(move_only&&) {}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- move_only() {}
-};
-
-move_only source() {return move_only();}
-const move_only csource() {return move_only();}
-
-void test(move_only) {}
-
-int main()
-{
- move_only a;
- const move_only ca = move_only();
-
- test(ca);
-}
diff --git a/test/std/utilities/utility/forward/move_only3.fail.cpp b/test/std/utilities/utility/forward/move_only3.fail.cpp
deleted file mode 100644
index 84c83ae48f8a..000000000000
--- a/test/std/utilities/utility/forward/move_only3.fail.cpp
+++ /dev/null
@@ -1,49 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test move
-
-#include <utility>
-#include <cassert>
-
-class move_only
-{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&&) {}
- move_only& operator=(move_only&&) {}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- move_only() {}
-};
-
-move_only source() {return move_only();}
-const move_only csource() {return move_only();}
-
-void test(move_only) {}
-
-int main()
-{
- move_only a;
- const move_only ca = move_only();
-
- test(std::move(ca));
-}
diff --git a/test/std/utilities/utility/forward/move_only4.fail.cpp b/test/std/utilities/utility/forward/move_only4.fail.cpp
deleted file mode 100644
index 5eeca89abe36..000000000000
--- a/test/std/utilities/utility/forward/move_only4.fail.cpp
+++ /dev/null
@@ -1,52 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// test move
-
-#include <utility>
-#include <cassert>
-
-#include <typeinfo>
-#include <stdio.h>
-
-class move_only
-{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&&) {}
- move_only& operator=(move_only&&) {}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- move_only() {}
-};
-
-move_only source() {return move_only();}
-const move_only csource() {return move_only();}
-
-void test(move_only) {}
-
-int main()
-{
- move_only a;
- const move_only ca = move_only();
-
- test(csource());
-}
diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp
index 9ef7bcff2ba8..c09c8815e16f 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp
@@ -24,7 +24,7 @@ int main()
{
{
typedef std::pair<int, short> P;
- const P p(3, 4);
+ const P p(3, static_cast<short>(4));
assert(std::get<0>(p) == 3);
assert(std::get<1>(p) == 4);
}
@@ -32,7 +32,7 @@ int main()
#if TEST_STD_VER > 11
{
typedef std::pair<int, short> P;
- constexpr P p1(3, 4);
+ constexpr P p1(3, static_cast<short>(4));
static_assert(std::get<0>(p1) == 3, "");
static_assert(std::get<1>(p1) == 4, "");
}
diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp
index edd2f3d0752f..5c38318d26da 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/get_const_rv.pass.cpp
@@ -28,7 +28,7 @@ int main()
{
{
typedef std::pair<std::unique_ptr<int>, short> P;
- const P p(std::unique_ptr<int>(new int(3)), 4);
+ const P p(std::unique_ptr<int>(new int(3)), static_cast<short>(4));
static_assert(std::is_same<const std::unique_ptr<int>&&, decltype(std::get<0>(std::move(p)))>::value, "");
static_assert(noexcept(std::get<0>(std::move(p))), "");
const std::unique_ptr<int>&& ptr = std::get<0>(std::move(p));
@@ -58,7 +58,7 @@ int main()
#if TEST_STD_VER > 11
{
typedef std::pair<int, short> P;
- constexpr const P p1(3, 4);
+ constexpr const P p1(3, static_cast<short>(4));
static_assert(std::get<0>(std::move(p1)) == 3, "");
static_assert(std::get<1>(std::move(p1)) == 4, "");
}
diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp
index 47b4c06134d9..2f8b6c1e8497 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp
@@ -34,7 +34,7 @@ int main()
{
{
typedef std::pair<int, short> P;
- P p(3, 4);
+ P p(3, static_cast<short>(4));
assert(std::get<0>(p) == 3);
assert(std::get<1>(p) == 4);
std::get<0>(p) = 5;
diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp
index aa5ca530913c..0601e4e73a74 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -21,12 +23,10 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<int>, short> P;
- P p(std::unique_ptr<int>(new int(3)), 4);
+ P p(std::unique_ptr<int>(new int(3)), static_cast<short>(4));
std::unique_ptr<int> ptr = std::get<0>(std::move(p));
assert(*ptr == 3);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
index 8c7dee2499dd..1ef2d9402fc3 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
@@ -7,24 +7,94 @@
//
//===----------------------------------------------------------------------===//
+// 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>
#include <memory>
#include <cassert>
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+using namespace ImplicitTypes; // Get implicitly archetypes
+
+template <class T1, class T1Arg,
+ bool CanCopy = true, bool CanConvert = CanCopy>
+void test_sfinae() {
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ using T2 = int const&;
+ static_assert(std::is_constructible<P1, T1Arg, T2>::value == CanCopy, "");
+ static_assert(test_convertible<P1, T1Arg, T2>() == CanConvert, "");
+ static_assert(std::is_constructible<P2, T2, T1Arg>::value == CanCopy, "");
+ static_assert(test_convertible<P2, T2, T1Arg>() == CanConvert, "");
+}
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<int>, short*> P;
P p(std::unique_ptr<int>(new int(3)), nullptr);
assert(*p.first == 3);
assert(p.second == nullptr);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ // Test non-const lvalue and rvalue types
+ test_sfinae<AllCtors, AllCtors&>();
+ test_sfinae<AllCtors, AllCtors&&>();
+ test_sfinae<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>();
+ test_sfinae<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>();
+ test_sfinae<CopyOnly, CopyOnly&>();
+ test_sfinae<CopyOnly, CopyOnly&&>();
+ test_sfinae<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
+ test_sfinae<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
+ test_sfinae<MoveOnly, MoveOnly&, false>();
+ test_sfinae<MoveOnly, MoveOnly&&>();
+ test_sfinae<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>();
+ test_sfinae<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, true, false>();
+ test_sfinae<NonCopyable, NonCopyable&, false>();
+ test_sfinae<NonCopyable, NonCopyable&&, false>();
+ test_sfinae<ExplicitTypes::NonCopyable, ExplicitTypes::NonCopyable&, false>();
+ test_sfinae<ExplicitTypes::NonCopyable, ExplicitTypes::NonCopyable&&, false>();
+ }
+ {
+ // Test converting types
+ test_sfinae<ConvertingType, int&>();
+ test_sfinae<ConvertingType, const int&>();
+ test_sfinae<ConvertingType, int&&>();
+ test_sfinae<ConvertingType, const int&&>();
+ test_sfinae<ExplicitTypes::ConvertingType, int&, true, false>();
+ test_sfinae<ExplicitTypes::ConvertingType, const int&, true, false>();
+ test_sfinae<ExplicitTypes::ConvertingType, int&&, true, false>();
+ test_sfinae<ExplicitTypes::ConvertingType, const int&&, true, false>();
+ }
+#if TEST_STD_VER > 11
+ { // explicit constexpr test
+ constexpr std::pair<ExplicitT, ExplicitT> p(42, 43);
+ static_assert(p.first.value == 42, "");
+ static_assert(p.second.value == 43, "");
+ }
+ { // implicit constexpr test
+ constexpr std::pair<ImplicitT, ImplicitT> p = {42, 43};
+ static_assert(p.first.value == 42, "");
+ static_assert(p.second.value == 43, "");
+ }
+#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_const_pair_U_V.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_const_pair_U_V.pass.cpp
index fdef5961437a..132443f66a7c 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/assign_const_pair_U_V.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_const_pair_U_V.pass.cpp
@@ -21,7 +21,7 @@ int main()
{
typedef std::pair<int, short> P1;
typedef std::pair<double, long> P2;
- P1 p1(3, 4);
+ P1 p1(3, static_cast<short>(4));
P2 p2;
p2 = p1;
assert(p2.first == 3);
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
new file mode 100644
index 000000000000..3f7066310002
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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& operator=(pair const& p);
+
+#include <utility>
+#include <memory>
+#include <cassert>
+
+
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable() = default;
+ CopyAssignable(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+struct MoveAssignable {
+ MoveAssignable() = default;
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+struct CountAssign {
+ static int copied;
+ static int moved;
+ static void reset() { copied = moved = 0; }
+ CountAssign() = default;
+ CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
+ CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
+};
+int CountAssign::copied = 0;
+int CountAssign::moved = 0;
+
+struct Incomplete;
+extern Incomplete inc_obj;
+
+int main()
+{
+ {
+ typedef std::pair<CopyAssignable, short> P;
+ const P p1(CopyAssignable(), 4);
+ P p2;
+ p2 = p1;
+ assert(p2.second == 4);
+ }
+ {
+ using P = std::pair<int&, int&&>;
+ int x = 42;
+ int y = 101;
+ int x2 = -1;
+ int y2 = 300;
+ P p1(x, std::move(y));
+ P p2(x2, std::move(y2));
+ p1 = p2;
+ assert(p1.first == x2);
+ assert(p1.second == y2);
+ }
+ {
+ using P = std::pair<int, NonAssignable>;
+ static_assert(!std::is_copy_assignable<P>::value, "");
+ }
+ {
+ CountAssign::reset();
+ using P = std::pair<CountAssign, CopyAssignable>;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = p2;
+ assert(CountAssign::copied == 1);
+ assert(CountAssign::moved == 0);
+ }
+ {
+ using P = std::pair<int, MoveAssignable>;
+ static_assert(!std::is_copy_assignable<P>::value, "");
+ }
+ {
+ using P = std::pair<int, Incomplete&>;
+ static_assert(!std::is_copy_assignable<P>::value, "");
+ P p(42, inc_obj);
+ assert(&p.second == &inc_obj);
+ }
+}
+
+struct Incomplete {};
+Incomplete inc_obj;
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp
new file mode 100644
index 000000000000..2623b800fff7
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES-ANY: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// pair& operator=(pair const& p);
+
+#include <utility>
+#include <memory>
+#include <cassert>
+
+struct NonAssignable {
+ NonAssignable() {}
+private:
+ NonAssignable& operator=(NonAssignable const&);
+};
+
+struct Incomplete;
+extern Incomplete inc_obj;
+
+int main()
+{
+ {
+ // Test that we don't constrain the assignment operator in C++03 mode.
+ // Since we don't have access control SFINAE having pair evaluate SFINAE
+ // may cause a hard error.
+ typedef std::pair<int, NonAssignable> P;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ }
+ {
+ typedef std::pair<int, Incomplete&> P;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ P p(42, inc_obj);
+ assert(&p.second == &inc_obj);
+ }
+}
+
+struct Incomplete {};
+Incomplete inc_obj;
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
index a753ee520dfa..38089200e4da 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -17,9 +19,35 @@
#include <memory>
#include <cassert>
+
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable() = default;
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+struct MoveAssignable {
+ MoveAssignable() = default;
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+struct CountAssign {
+ static int copied;
+ static int moved;
+ static void reset() { copied = moved = 0; }
+ CountAssign() = default;
+ CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
+ CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
+};
+int CountAssign::copied = 0;
+int CountAssign::moved = 0;
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<int>, short> P;
P p1(std::unique_ptr<int>(new int(3)), 4);
@@ -28,5 +56,41 @@ int main()
assert(*p2.first == 3);
assert(p2.second == 4);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ using P = std::pair<int&, int&&>;
+ int x = 42;
+ int y = 101;
+ int x2 = -1;
+ int y2 = 300;
+ P p1(x, std::move(y));
+ P p2(x2, std::move(y2));
+ p1 = std::move(p2);
+ assert(p1.first == x2);
+ assert(p1.second == y2);
+ }
+ {
+ using P = std::pair<int, NonAssignable>;
+ static_assert(!std::is_move_assignable<P>::value, "");
+ }
+ {
+ // The move decays to the copy constructor
+ CountAssign::reset();
+ using P = std::pair<CountAssign, CopyAssignable>;
+ static_assert(std::is_move_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = std::move(p2);
+ assert(CountAssign::moved == 0);
+ assert(CountAssign::copied == 1);
+ }
+ {
+ CountAssign::reset();
+ using P = std::pair<CountAssign, MoveAssignable>;
+ static_assert(std::is_move_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = std::move(p2);
+ assert(CountAssign::moved == 1);
+ assert(CountAssign::copied == 0);
+ }
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp
index a200390f4882..76dfc3f65a23 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -29,15 +31,13 @@ struct Derived
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<Derived>, short> P1;
typedef std::pair<std::unique_ptr<Base>, long> P2;
- P1 p1(std::unique_ptr<Derived>(), 4);
+ P1 p1(std::unique_ptr<Derived>(), static_cast<short>(4));
P2 p2;
p2 = std::move(p1);
assert(p2.first == nullptr);
assert(p2.second == 4);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp
new file mode 100644
index 000000000000..ef7bebcf5c29
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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& operator=(tuple<U, V>&& p);
+
+#include <utility>
+#include <tuple>
+#include <array>
+#include <memory>
+#include <cassert>
+
+// Clang warns about missing braces when initializing std::array.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
+
+struct CountingType {
+ static int constructed;
+ static int copy_constructed;
+ static int move_constructed;
+ static int assigned;
+ static int copy_assigned;
+ static int move_assigned;
+ static void reset() {
+ constructed = copy_constructed = move_constructed = 0;
+ assigned = copy_assigned = move_assigned = 0;
+ }
+ CountingType() : value(0) { ++constructed; }
+ CountingType(int v) : value(v) { ++constructed; }
+ CountingType(CountingType const& o) : value(o.value) { ++constructed; ++copy_constructed; }
+ CountingType(CountingType&& o) : value(o.value) { ++constructed; ++move_constructed; o.value = -1;}
+
+ CountingType& operator=(CountingType const& o) {
+ ++assigned;
+ ++copy_assigned;
+ value = o.value;
+ return *this;
+ }
+ CountingType& operator=(CountingType&& o) {
+ ++assigned;
+ ++move_assigned;
+ value = o.value;
+ o.value = -1;
+ return *this;
+ }
+ int value;
+};
+int CountingType::constructed;
+int CountingType::copy_constructed;
+int CountingType::move_constructed;
+int CountingType::assigned;
+int CountingType::copy_assigned;
+int CountingType::move_assigned;
+
+int main()
+{
+ using C = CountingType;
+ {
+ using P = std::pair<int, C>;
+ using T = std::tuple<int, C>;
+ T t(42, C{42});
+ P p(101, C{101});
+ C::reset();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 1);
+ assert(C::copy_assigned == 1);
+ assert(C::move_assigned == 0);
+ assert(p.first == 42);
+ assert(p.second.value == 42);
+ }
+ {
+ using P = std::pair<int, C>;
+ using T = std::tuple<int, C>;
+ T t(42, -42);
+ P p(101, 101);
+ C::reset();
+ p = std::move(t);
+ assert(C::constructed == 0);
+ assert(C::assigned == 1);
+ assert(C::copy_assigned == 0);
+ assert(C::move_assigned == 1);
+ assert(p.first == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 2);
+ assert(C::move_assigned == 0);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 2);
+ assert(C::move_assigned == 0);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset();
+ p = std::move(t);
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 0);
+ assert(C::move_assigned == 2);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
index 2041b39c2dc9..bf19d1abe4c5 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -16,25 +18,34 @@
#include <utility>
#include <cassert>
-class A
-{
- int data_;
-public:
- A(int data) : data_(data) {}
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+using namespace ImplicitTypes; // Get implicitly archetypes
- bool operator==(const A& a) const {return data_ == a.data_;}
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
+ int value;
};
-#if _LIBCPP_STD_VER > 11
-class AC
-{
- int data_;
-public:
- constexpr AC(int data) : data_(data) {}
-
- constexpr bool operator==(const AC& a) const {return data_ == a.data_;}
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
+ int value;
};
-#endif
+
+template <class T1,
+ bool CanCopy = true, bool CanConvert = CanCopy>
+void test_sfinae() {
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ using T1Arg = T1 const&;
+ using T2 = int const&;
+ static_assert(std::is_constructible<P1, T1Arg, T2>::value == CanCopy, "");
+ static_assert(test_convertible<P1, T1Arg, T2>() == CanConvert, "");
+ static_assert(std::is_constructible<P2, T2, T1Arg>::value == CanCopy, "");
+ static_assert(test_convertible<P2, T2, T1Arg>() == CanConvert, "");
+}
int main()
{
@@ -45,13 +56,22 @@ int main()
assert(p.second == nullptr);
}
{
- typedef std::pair<A, int> P;
+ typedef std::pair<ImplicitT, int> P;
P p(1, 2);
- assert(p.first == A(1));
+ assert(p.first.value == 1);
assert(p.second == 2);
}
-
-#if _LIBCPP_STD_VER > 11
+ {
+ test_sfinae<AllCtors>();
+ test_sfinae<ExplicitTypes::AllCtors, true, false>();
+ test_sfinae<CopyOnly>();
+ test_sfinae<ExplicitTypes::CopyOnly, true, false>();
+ test_sfinae<MoveOnly, false>();
+ test_sfinae<ExplicitTypes::MoveOnly, false>();
+ test_sfinae<NonCopyable, false>();
+ test_sfinae<ExplicitTypes::NonCopyable, false>();
+ }
+#if TEST_STD_VER > 11
{
typedef std::pair<float, short*> P;
constexpr P p(3.5f, 0);
@@ -59,10 +79,20 @@ int main()
static_assert(p.second == nullptr, "");
}
{
- typedef std::pair<AC, int> P;
- constexpr P p(1, 2);
- static_assert(p.first == AC(1), "");
- static_assert(p.second == 2, "");
+ using P = std::pair<ExplicitT, int>;
+ constexpr ExplicitT e(42);
+ constexpr int x = 10;
+ constexpr P p(e, x);
+ static_assert(p.first.value == 42, "");
+ static_assert(p.second == 10, "");
+ }
+ {
+ using P = std::pair<ImplicitT, int>;
+ constexpr ImplicitT e(42);
+ constexpr int x = 10;
+ constexpr P p = {e, x};
+ static_assert(p.first.value == 42, "");
+ static_assert(p.second == 10, "");
}
#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second_cxx03.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second_cxx03.pass.cpp
new file mode 100644
index 000000000000..8c56c2003460
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/const_first_const_second_cxx03.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// pair(const T1& x, const T2& y);
+
+#include <utility>
+#include <cassert>
+
+class A
+{
+ int data_;
+public:
+ A(int data) : data_(data) {}
+
+ bool operator==(const A& a) const {return data_ == a.data_;}
+};
+
+int main()
+{
+ {
+ typedef std::pair<float, short*> P;
+ P p(3.5f, 0);
+ assert(p.first == 3.5f);
+ assert(p.second == nullptr);
+ }
+ {
+ typedef std::pair<A, int> P;
+ P p(1, 2);
+ assert(p.first == A(1));
+ assert(p.second == 2);
+ }
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
index 286cce47f050..ade8130d7822 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
@@ -7,27 +7,152 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
-// template <class U, class V> pair(const pair<U, V>& p);
+// template <class U, class V> EXPLICIT constexpr pair(const pair<U, V>& p);
#include <utility>
#include <cassert>
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+using namespace ImplicitTypes; // Get implicitly archetypes
+
+template <class T1, class U1,
+ bool CanCopy = true, bool CanConvert = CanCopy>
+void test_pair_const()
+{
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ using UP1 = std::pair<U1, int> const&;
+ using UP2 = std::pair<int, U1> const&;
+ static_assert(std::is_constructible<P1, UP1>::value == CanCopy, "");
+ static_assert(test_convertible<P1, UP1>() == CanConvert, "");
+ static_assert(std::is_constructible<P2, UP2>::value == CanCopy, "");
+ static_assert(test_convertible<P2, UP2>() == CanConvert, "");
+}
+
+template <class T, class U>
+struct DPair : public std::pair<T, U> {
+ using Base = std::pair<T, U>;
+ using Base::Base;
+};
+
+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;
+};
+
int main()
{
{
typedef std::pair<int, short> P1;
typedef std::pair<double, long> P2;
- P1 p1(3, 4);
- P2 p2 = p1;
+ const P1 p1(3, 4);
+ const P2 p2 = p1;
assert(p2.first == 3);
assert(p2.second == 4);
}
+ {
+ // We allow derived types to use this constructor
+ using P1 = DPair<long, long>;
+ using P2 = std::pair<int, int>;
+ P1 p1(42, 101);
+ P2 p2(p1);
+ assert(p2.first == 42);
+ assert(p2.second = 101);
+ }
+ {
+ test_pair_const<AllCtors, AllCtors>(); // copy construction
+ test_pair_const<AllCtors, AllCtors&>();
+ test_pair_const<AllCtors, AllCtors&&>();
+ test_pair_const<AllCtors, const AllCtors&>();
+ test_pair_const<AllCtors, const AllCtors&&>();
+
+ test_pair_const<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors>(); // copy construction
+ test_pair_const<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>();
+ test_pair_const<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>();
+ test_pair_const<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&, true, false>();
+ test_pair_const<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&&, true, false>();
+
+ test_pair_const<MoveOnly, MoveOnly, false>(); // copy construction
+ test_pair_const<MoveOnly, MoveOnly&, false>();
+ test_pair_const<MoveOnly, MoveOnly&&, false>();
+
+ test_pair_const<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly, false>(); // copy construction
+ test_pair_const<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>();
+ test_pair_const<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, false>();
+
+ test_pair_const<CopyOnly, CopyOnly>();
+ test_pair_const<CopyOnly, CopyOnly&>();
+ test_pair_const<CopyOnly, CopyOnly&&>();
+
+ test_pair_const<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>();
+ test_pair_const<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
+ test_pair_const<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
-#if _LIBCPP_STD_VER > 11
+ test_pair_const<NonCopyable, NonCopyable, false>();
+ test_pair_const<NonCopyable, NonCopyable&, false>();
+ test_pair_const<NonCopyable, NonCopyable&&, false>();
+ test_pair_const<NonCopyable, const NonCopyable&, false>();
+ test_pair_const<NonCopyable, const NonCopyable&&, false>();
+ }
+
+ { // Test construction of references
+ test_pair_const<NonCopyable&, NonCopyable&>();
+ test_pair_const<NonCopyable&, NonCopyable&&>();
+ test_pair_const<NonCopyable&, NonCopyable const&, false>();
+ test_pair_const<NonCopyable const&, NonCopyable&&>();
+ test_pair_const<NonCopyable&&, NonCopyable&&, false>();
+
+ test_pair_const<ConvertingType&, int, false>();
+ test_pair_const<ExplicitTypes::ConvertingType&, int, false>();
+ // Unfortunately the below conversions are allowed and create dangling
+ // references.
+ //test_pair_const<ConvertingType&&, int>();
+ //test_pair_const<ConvertingType const&, int>();
+ //test_pair_const<ConvertingType const&&, int>();
+ // But these are not because the converting constructor is explicit.
+ test_pair_const<ExplicitTypes::ConvertingType&&, int, false>();
+ test_pair_const<ExplicitTypes::ConvertingType const&, int, false>();
+ test_pair_const<ExplicitTypes::ConvertingType const&&, int, false>();
+
+ }
+ {
+ test_pair_const<AllCtors, int, false>();
+ test_pair_const<ExplicitTypes::AllCtors, int, false>();
+ test_pair_const<ConvertingType, int>();
+ test_pair_const<ExplicitTypes::ConvertingType, int, true, false>();
+
+ test_pair_const<ConvertingType, int>();
+ test_pair_const<ConvertingType, ConvertingType>();
+ test_pair_const<ConvertingType, ConvertingType const&>();
+ test_pair_const<ConvertingType, ConvertingType&>();
+ test_pair_const<ConvertingType, ConvertingType&&>();
+
+ test_pair_const<ExplicitTypes::ConvertingType, int, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, int&, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, const int&, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, int&&, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, const int&&, true, false>();
+
+ test_pair_const<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType>();
+ test_pair_const<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType const&, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&, true, false>();
+ test_pair_const<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&&, true, false>();
+ }
+#if TEST_STD_VER > 11
{
typedef std::pair<int, short> P1;
typedef std::pair<double, long> P2;
@@ -36,5 +161,21 @@ int main()
static_assert(p2.first == 3, "");
static_assert(p2.second == 4, "");
}
+ {
+ using P1 = std::pair<int, int>;
+ using P2 = std::pair<ExplicitT, ExplicitT>;
+ constexpr P1 p1(42, 101);
+ constexpr P2 p2(p1);
+ static_assert(p2.first.value == 42, "");
+ static_assert(p2.second.value == 101, "");
+ }
+ {
+ using P1 = std::pair<int, int>;
+ using P2 = std::pair<ImplicitT, ImplicitT>;
+ constexpr P1 p1(42, 101);
+ constexpr P2 p2 = p1;
+ static_assert(p2.first.value == 42, "");
+ static_assert(p2.second.value == 101, "");
+ }
#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.pass.cpp
new file mode 100644
index 000000000000..fbf461f9b7e0
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class U, class V> pair(const pair<U, V>& p);
+
+#include <utility>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef std::pair<int, short> P1;
+ typedef std::pair<double, long> P2;
+ const P1 p1(3, static_cast<short>(4));
+ const P2 p2 = p1;
+ assert(p2.first == 3);
+ assert(p2.second == 4);
+ }
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp
index 1117db3297b8..1003f3c8b68f 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp
@@ -22,7 +22,7 @@ int main()
{
{
typedef std::pair<int, short> P1;
- P1 p1(3, 4);
+ P1 p1(3, static_cast<short>(4));
P1 p2 = p1;
assert(p2.first == 3);
assert(p2.second == 4);
@@ -30,7 +30,7 @@ int main()
#if TEST_STD_VER > 11
{
typedef std::pair<int, short> P1;
- constexpr P1 p1(3, 4);
+ constexpr P1 p1(3, static_cast<short>(4));
constexpr P1 p2 = p1;
static_assert(p2.first == 3, "");
static_assert(p2.second == 4, "");
diff --git a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp
index 97182d24d021..ace00a16f21e 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp
@@ -27,14 +27,15 @@
#include <cassert>
#include "test_macros.h"
+#include "archetypes.hpp"
int main()
{
{
- typedef std::pair<float, short*> P;
- P p;
- assert(p.first == 0.0f);
- assert(p.second == nullptr);
+ typedef std::pair<float, short*> P;
+ P p;
+ assert(p.first == 0.0f);
+ assert(p.second == nullptr);
}
#if TEST_STD_VER >= 11
{
@@ -43,5 +44,12 @@ int main()
static_assert(p.first == 0.0f, "");
static_assert(p.second == nullptr, "");
}
+ {
+ using NoDefault = ImplicitTypes::NoDefault;
+ using P = std::pair<int, NoDefault>;
+ static_assert(!std::is_default_constructible<P>::value, "");
+ using P2 = std::pair<NoDefault, int>;
+ static_assert(!std::is_default_constructible<P>::value, "");
+ }
#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/dtor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/dtor.pass.cpp
new file mode 100644
index 000000000000..2d87e7ababab
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/dtor.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
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// ~pair()
+
+
+#include <utility>
+#include <type_traits>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main()
+{
+ static_assert((std::is_trivially_destructible<
+ std::pair<int, float> >::value), "");
+ static_assert((!std::is_trivially_destructible<
+ std::pair<int, std::string> >::value), "");
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp
index 06cb5e5658c9..99e00b025da2 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp
@@ -31,7 +31,7 @@ int main()
{
typedef std::pair<int, short> P1;
static_assert(std::is_move_constructible<P1>::value, "");
- P1 p1(3, 4);
+ P1 p1(3, static_cast<short>(4));
P1 p2 = std::move(p1);
assert(p2.first == 3);
assert(p2.second == 4);
diff --git a/test/std/utilities/utility/pairs/pairs.pair/not_constexpr_cxx11.fail.cpp b/test/std/utilities/utility/pairs/pairs.pair/not_constexpr_cxx11.fail.cpp
new file mode 100644
index 000000000000..3704dcc32edc
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/not_constexpr_cxx11.fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: c++11
+
+// <utility>
+
+// Test that only the default constructor is constexpr in C++11
+
+#include <utility>
+#include <cassert>
+
+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;
+};
+
+int main()
+{
+ {
+ using P = std::pair<int, int>;
+ constexpr int x = 42;
+ constexpr P default_p{};
+ constexpr P copy_p(default_p);
+ constexpr P const_U_V(x, x); // expected-error {{must be initialized by a constant expression}}
+ constexpr P U_V(42, 101); // expected-error {{must be initialized by a constant expression}}
+ }
+ {
+ using P = std::pair<ExplicitT, ExplicitT>;
+ constexpr std::pair<int, int> other;
+ constexpr ExplicitT e(99);
+ constexpr P const_U_V(e, e); // expected-error {{must be initialized by a constant expression}}
+ constexpr P U_V(42, 101); // expected-error {{must be initialized by a constant expression}}
+ constexpr P pair_U_V(other); // expected-error {{must be initialized by a constant expression}}
+ }
+ {
+ using P = std::pair<ImplicitT, ImplicitT>;
+ constexpr std::pair<int, int> other;
+ constexpr ImplicitT i = 99;
+ constexpr P const_U_V = {i, i}; // expected-error {{must be initialized by a constant expression}}
+ constexpr P U_V = {42, 101}; // expected-error {{must be initialized by a constant expression}}
+ constexpr P pair_U_V = other; // expected-error {{must be initialized by a constant expression}}
+ }
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
index 5fb6c98979b5..2856190841c0 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -17,6 +19,24 @@
#include <memory>
#include <cassert>
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+using namespace ImplicitTypes; // Get implicitly archetypes
+
+template <class T1, class U1,
+ bool CanCopy = true, bool CanConvert = CanCopy>
+void test_pair_rv()
+{
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ using UP1 = std::pair<U1, int>&&;
+ using UP2 = std::pair<int, U1>&&;
+ static_assert(std::is_constructible<P1, UP1>::value == CanCopy, "");
+ static_assert(test_convertible<P1, UP1>() == CanConvert, "");
+ static_assert(std::is_constructible<P2, UP2>::value == CanCopy, "");
+ static_assert(test_convertible<P2, UP2>() == CanConvert, "");
+}
+
struct Base
{
virtual ~Base() {}
@@ -27,9 +47,25 @@ struct Derived
{
};
+
+template <class T, class U>
+struct DPair : public std::pair<T, U> {
+ using Base = std::pair<T, U>;
+ using Base::Base;
+};
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<Derived>, short> P1;
typedef std::pair<std::unique_ptr<Base>, long> P2;
@@ -38,5 +74,104 @@ int main()
assert(p2.first == nullptr);
assert(p2.second == 4);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ // We allow derived types to use this constructor
+ using P1 = DPair<long, long>;
+ using P2 = std::pair<int, int>;
+ P1 p1(42, 101);
+ P2 p2(std::move(p1));
+ assert(p2.first == 42);
+ assert(p2.second = 101);
+ }
+ {
+ test_pair_rv<AllCtors, AllCtors>();
+ test_pair_rv<AllCtors, AllCtors&>();
+ test_pair_rv<AllCtors, AllCtors&&>();
+ test_pair_rv<AllCtors, const AllCtors&>();
+ test_pair_rv<AllCtors, const AllCtors&&>();
+
+ test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors>();
+ test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>();
+ test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>();
+ test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&, true, false>();
+ test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&&, true, false>();
+
+ test_pair_rv<MoveOnly, MoveOnly>();
+ test_pair_rv<MoveOnly, MoveOnly&, false>();
+ test_pair_rv<MoveOnly, MoveOnly&&>();
+
+ test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly>(); // copy construction
+ test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>();
+ test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, true, false>();
+
+ test_pair_rv<CopyOnly, CopyOnly>();
+ test_pair_rv<CopyOnly, CopyOnly&>();
+ test_pair_rv<CopyOnly, CopyOnly&&>();
+
+ test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>();
+ test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
+ test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
+
+ test_pair_rv<NonCopyable, NonCopyable, false>();
+ test_pair_rv<NonCopyable, NonCopyable&, false>();
+ test_pair_rv<NonCopyable, NonCopyable&&, false>();
+ test_pair_rv<NonCopyable, const NonCopyable&, false>();
+ test_pair_rv<NonCopyable, const NonCopyable&&, false>();
+ }
+ { // Test construction of references
+ test_pair_rv<NonCopyable&, NonCopyable&>();
+ test_pair_rv<NonCopyable&, NonCopyable&&>();
+ test_pair_rv<NonCopyable&, NonCopyable const&, false>();
+ test_pair_rv<NonCopyable const&, NonCopyable&&>();
+ test_pair_rv<NonCopyable&&, NonCopyable&&>();
+
+ test_pair_rv<ConvertingType&, int, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType&, int, false>();
+ // Unfortunately the below conversions are allowed and create dangling
+ // references.
+ //test_pair_rv<ConvertingType&&, int>();
+ //test_pair_rv<ConvertingType const&, int>();
+ //test_pair_rv<ConvertingType const&&, int>();
+ // But these are not because the converting constructor is explicit.
+ test_pair_rv<ExplicitTypes::ConvertingType&&, int, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType const&, int, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType const&&, int, false>();
+ }
+ {
+ test_pair_rv<AllCtors, int, false>();
+ test_pair_rv<ExplicitTypes::AllCtors, int, false>();
+ test_pair_rv<ConvertingType, int>();
+ test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
+
+ test_pair_rv<ConvertingType, int>();
+ test_pair_rv<ConvertingType, ConvertingType>();
+ test_pair_rv<ConvertingType, ConvertingType const&>();
+ test_pair_rv<ConvertingType, ConvertingType&>();
+ test_pair_rv<ConvertingType, ConvertingType&&>();
+
+ test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, int&, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, const int&, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, int&&, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, const int&&, true, false>();
+
+ test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType>();
+ test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType const&, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&, true, false>();
+ test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&&, true, false>();
+ }
+#if TEST_STD_VER > 11
+ { // explicit constexpr test
+ constexpr std::pair<int, int> p1(42, 43);
+ constexpr std::pair<ExplicitT, ExplicitT> p2(std::move(p1));
+ static_assert(p2.first.value == 42, "");
+ static_assert(p2.second.value == 43, "");
+ }
+ { // implicit constexpr test
+ constexpr std::pair<int, int> p1(42, 43);
+ constexpr std::pair<ImplicitT, ImplicitT> p2 = std::move(p1);
+ static_assert(p2.first.value == 42, "");
+ static_assert(p2.second.value == 43, "");
+ }
+#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/special_member_generation_test.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/special_member_generation_test.pass.cpp
new file mode 100644
index 000000000000..1331a3153641
--- /dev/null
+++ b/test/std/utilities/utility/pairs/pairs.pair/special_member_generation_test.pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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 T, class U> struct pair;
+
+// pair(pair const&) = default;
+// pair(pair &&) = default;
+// pair& operator=(pair const&);
+// pair& operator=(pair&&);
+
+// Test that the copy/move constructors and assignment operators are
+// correctly defined or deleted based on the properties of `T` and `U`.
+
+#include <cassert>
+#include <string>
+#include <tuple>
+
+#include "archetypes.hpp"
+using namespace ImplicitTypes; // Get implicitly archetypes
+
+namespace ConstructorTest {
+
+template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ static_assert(std::is_copy_constructible<P1>::value == CanCopy, "");
+ static_assert(std::is_move_constructible<P1>::value == CanMove, "");
+ static_assert(std::is_copy_constructible<P2>::value == CanCopy, "");
+ static_assert(std::is_move_constructible<P2>::value == CanMove, "");
+};
+
+} // namespace ConstructorTest
+
+void test_constructors_exist() {
+ using namespace ConstructorTest;
+ {
+ test<int>();
+ test<int &>();
+ test<int &&, false, true>();
+ test<const int>();
+ test<const int &>();
+ test<const int &&, false, true>();
+ }
+ {
+ test<Copyable>();
+ test<Copyable &>();
+ test<Copyable &&, false, true>();
+ }
+ {
+ test<NonCopyable, false>();
+ test<NonCopyable &, true>();
+ test<NonCopyable &&, false, true>();
+ }
+ {
+ // Even though CopyOnly has an explicitly deleted move constructor
+ // pair's move constructor is only implicitly deleted and therefore
+ // it doesn't participate in overload resolution.
+ test<CopyOnly, true, true>();
+ test<CopyOnly &, true>();
+ test<CopyOnly &&, false, true>();
+ }
+ {
+ test<MoveOnly, false, true>();
+ test<MoveOnly &, true>();
+ test<MoveOnly &&, false, true>();
+ }
+}
+
+namespace AssignmentOperatorTest {
+
+template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
+ using P1 = std::pair<T1, int>;
+ using P2 = std::pair<int, T1>;
+ static_assert(std::is_copy_assignable<P1>::value == CanCopy, "");
+ static_assert(std::is_move_assignable<P1>::value == CanMove, "");
+ static_assert(std::is_copy_assignable<P2>::value == CanCopy, "");
+ static_assert(std::is_move_assignable<P2>::value == CanMove, "");
+};
+
+} // namespace AssignmentOperatorTest
+
+void test_assignment_operator_exists() {
+ using namespace AssignmentOperatorTest;
+ {
+ test<int>();
+ test<int &>();
+ test<int &&>();
+ test<const int, false>();
+ test<const int &, false>();
+ test<const int &&, false>();
+ }
+ {
+ test<Copyable>();
+ test<Copyable &>();
+ test<Copyable &&>();
+ }
+ {
+ test<NonCopyable, false>();
+ test<NonCopyable &, false>();
+ test<NonCopyable &&, false>();
+ }
+ {
+ test<CopyOnly, true>();
+ test<CopyOnly &, true>();
+ test<CopyOnly &&, true>();
+ }
+ {
+ test<MoveOnly, false, true>();
+ test<MoveOnly &, false, false>();
+ test<MoveOnly &&, false, true>();
+ }
+}
+
+int main() {
+ test_constructors_exist();
+ test_assignment_operator_exists();
+}
diff --git a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp
index dfea61eeacdb..95b1f66d64aa 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp
@@ -29,8 +29,8 @@ int main()
{
{
typedef std::pair<int, short> P1;
- P1 p1(3, 4);
- P1 p2(5, 6);
+ P1 p1(3, static_cast<short>(4));
+ P1 p2(5, static_cast<short>(6));
p1.swap(p2);
assert(p1.first == 5);
assert(p1.second == 6);
diff --git a/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp
index 53cf56700df8..200f044c6359 100644
--- a/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp
@@ -32,19 +32,25 @@ int main()
typedef std::pair<int, short> P;
{
static_assert(std::is_copy_constructible<P>::value, "");
+#if !defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
static_assert(std::is_trivially_copy_constructible<P>::value, "");
+#endif
}
#if TEST_STD_VER >= 11
{
static_assert(std::is_move_constructible<P>::value, "");
+#if !defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
static_assert(std::is_trivially_move_constructible<P>::value, "");
+#endif
}
{
using P1 = std::pair<Dummy, int>;
static_assert(!std::is_copy_constructible<P1>::value, "");
static_assert(!std::is_trivially_copy_constructible<P1>::value, "");
static_assert(std::is_move_constructible<P1>::value, "");
+#if !defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
static_assert(std::is_trivially_move_constructible<P1>::value, "");
+#endif
}
#endif
}
diff --git a/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp b/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
index 9ba8532ab29e..3b994dfd4dfe 100644
--- a/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.spec/comparison.pass.cpp
@@ -21,12 +21,14 @@
#include <utility>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
typedef std::pair<int, short> P;
- P p1(3, 4);
- P p2(3, 4);
+ P p1(3, static_cast<short>(4));
+ P p2(3, static_cast<short>(4));
assert( (p1 == p2));
assert(!(p1 != p2));
assert(!(p1 < p2));
@@ -36,8 +38,8 @@ int main()
}
{
typedef std::pair<int, short> P;
- P p1(2, 4);
- P p2(3, 4);
+ P p1(2, static_cast<short>(4));
+ P p2(3, static_cast<short>(4));
assert(!(p1 == p2));
assert( (p1 != p2));
assert( (p1 < p2));
@@ -47,8 +49,8 @@ int main()
}
{
typedef std::pair<int, short> P;
- P p1(3, 2);
- P p2(3, 4);
+ P p1(3, static_cast<short>(2));
+ P p2(3, static_cast<short>(4));
assert(!(p1 == p2));
assert( (p1 != p2));
assert( (p1 < p2));
@@ -58,8 +60,8 @@ int main()
}
{
typedef std::pair<int, short> P;
- P p1(3, 4);
- P p2(2, 4);
+ P p1(3, static_cast<short>(4));
+ P p2(2, static_cast<short>(4));
assert(!(p1 == p2));
assert( (p1 != p2));
assert(!(p1 < p2));
@@ -69,8 +71,8 @@ int main()
}
{
typedef std::pair<int, short> P;
- P p1(3, 4);
- P p2(3, 2);
+ P p1(3, static_cast<short>(4));
+ P p2(3, static_cast<short>(2));
assert(!(p1 == p2));
assert( (p1 != p2));
assert(!(p1 < p2));
@@ -79,11 +81,11 @@ int main()
assert( (p1 >= p2));
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef std::pair<int, short> P;
- constexpr P p1(3, 4);
- constexpr P p2(3, 2);
+ constexpr P p1(3, static_cast<short>(4));
+ constexpr P p2(3, static_cast<short>(2));
static_assert(!(p1 == p2), "");
static_assert( (p1 != p2), "");
static_assert(!(p1 < p2), "");
diff --git a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp
index 4a6d71e7b9c8..3586243f8bac 100644
--- a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp
@@ -15,34 +15,35 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
+
int main()
{
{
typedef std::pair<int, short> P1;
- P1 p1 = std::make_pair(3, 4);
+ P1 p1 = std::make_pair(3, static_cast<short>(4));
assert(p1.first == 3);
assert(p1.second == 4);
}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
{
typedef std::pair<std::unique_ptr<int>, short> P1;
- P1 p1 = std::make_pair(std::unique_ptr<int>(new int(3)), 4);
+ P1 p1 = std::make_pair(std::unique_ptr<int>(new int(3)), static_cast<short>(4));
assert(*p1.first == 3);
assert(p1.second == 4);
}
{
typedef std::pair<std::unique_ptr<int>, short> P1;
- P1 p1 = std::make_pair(nullptr, 4);
+ P1 p1 = std::make_pair(nullptr, static_cast<short>(4));
assert(p1.first == nullptr);
assert(p1.second == 4);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#if _LIBCPP_STD_VER > 11
+#endif
+#if TEST_STD_VER >= 14
{
typedef std::pair<int, short> P1;
- constexpr P1 p1 = std::make_pair(3, 4);
+ constexpr P1 p1 = std::make_pair(3, static_cast<short>(4));
static_assert(p1.first == 3, "");
static_assert(p1.second == 4, "");
}
diff --git a/test/std/utilities/utility/pairs/pairs.spec/non_member_swap.pass.cpp b/test/std/utilities/utility/pairs/pairs.spec/non_member_swap.pass.cpp
index d9d8f27b5225..62fa94247946 100644
--- a/test/std/utilities/utility/pairs/pairs.spec/non_member_swap.pass.cpp
+++ b/test/std/utilities/utility/pairs/pairs.spec/non_member_swap.pass.cpp
@@ -20,8 +20,8 @@ int main()
{
{
typedef std::pair<int, short> P1;
- P1 p1(3, 4);
- P1 p2(5, 6);
+ P1 p1(3, static_cast<short>(4));
+ P1 p2(5, static_cast<short>(6));
swap(p1, p2);
assert(p1.first == 5);
assert(p1.second == 6);
diff --git a/test/std/utilities/utility/utility.inplace/inplace.pass.cpp b/test/std/utilities/utility/utility.inplace/inplace.pass.cpp
new file mode 100644
index 000000000000..e87c6f399e93
--- /dev/null
+++ b/test/std/utilities/utility/utility.inplace/inplace.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
+
+// <utility>
+
+// struct in_place_t {
+// explicit in_place_t() = default;
+// };
+// inline constexpr in_place_t in_place{};
+
+// template <class T>
+// struct in_place_type_t {
+// explicit in_place_type_t() = default;
+// };
+// template <class T>
+// inline constexpr in_place_type_t<T> in_place_type{};
+
+// template <size_t I>
+// struct in_place_index_t {
+// explicit in_place_index_t() = default;
+// };
+// template <size_t I>
+// inline constexpr in_place_index_t<I> in_place_index{};
+
+#include <utility>
+#include <cassert>
+#include <memory>
+
+#include "test_macros.h"
+#include "type_id.h"
+
+template <class Tp, class Up>
+constexpr bool check_tag(Up) {
+ return std::is_same<Tp, std::decay_t<Tp>>::value
+ && std::is_same<Tp, Up>::value;
+}
+
+int main() {
+ // test in_place_t
+ {
+ using T = std::in_place_t;
+ static_assert(check_tag<T>(std::in_place));
+ }
+ // test in_place_type_t
+ {
+ using T1 = std::in_place_type_t<void>;
+ using T2 = std::in_place_type_t<int>;
+ using T3 = std::in_place_type_t<const int>;
+ static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value);
+ static_assert(!std::is_same<T2, T3>::value);
+ static_assert(check_tag<T1>(std::in_place_type<void>));
+ static_assert(check_tag<T2>(std::in_place_type<int>));
+ static_assert(check_tag<T3>(std::in_place_type<const int>));
+ }
+ // test in_place_index_t
+ {
+ using T1 = std::in_place_index_t<0>;
+ using T2 = std::in_place_index_t<1>;
+ using T3 = std::in_place_index_t<static_cast<size_t>(-1)>;
+ static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value);
+ static_assert(!std::is_same<T2, T3>::value);
+ static_assert(check_tag<T1>(std::in_place_index<0>));
+ static_assert(check_tag<T2>(std::in_place_index<1>));
+ static_assert(check_tag<T3>(std::in_place_index<static_cast<size_t>(-1)>));
+ }
+}
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
new file mode 100644
index 000000000000..77fd1719ff33
--- /dev/null
+++ b/test/std/utilities/variant/variant.bad_variant_access/bad_variant_access.pass.cpp
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+/*
+
+ class bad_variant_access : public exception {
+public:
+ bad_variant_access() noexcept;
+ virtual const char* what() const noexcept;
+};
+
+*/
+
+#include <cassert>
+#include <exception>
+#include <type_traits>
+#include <variant>
+
+int main() {
+ static_assert(std::is_base_of<std::exception, std::bad_variant_access>::value,
+ "");
+ static_assert(noexcept(std::bad_variant_access{}), "must be noexcept");
+ static_assert(noexcept(std::bad_variant_access{}.what()), "must be noexcept");
+ std::bad_variant_access ex;
+ assert(ex.what());
+}
diff --git a/test/std/utilities/utility/forward/forward6.fail.cpp b/test/std/utilities/variant/variant.general/nothing_to_do.pass.cpp
index 1f4b37d946ca..8fb3817dba9b 100644
--- a/test/std/utilities/utility/forward/forward6.fail.cpp
+++ b/test/std/utilities/variant/variant.general/nothing_to_do.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -7,16 +8,4 @@
//
//===----------------------------------------------------------------------===//
-// test forward
-
-#include <utility>
-
-struct A
-{
-};
-
-int main()
-{
- A a;
- std::forward(a); // error
-}
+int main() {}
diff --git a/test/std/utilities/variant/variant.get/get_if_index.pass.cpp b/test/std/utilities/variant/variant.get/get_if_index.pass.cpp
new file mode 100644
index 000000000000..94cc08031fda
--- /dev/null
+++ b/test/std/utilities/variant/variant.get/get_if_index.pass.cpp
@@ -0,0 +1,132 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <size_t I, class... Types>
+// constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
+// get_if(variant<Types...>* v) noexcept;
+// template <size_t I, class... Types>
+// constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
+// get_if(const variant<Types...>* v) noexcept;
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include <cassert>
+#include <memory>
+#include <variant>
+
+void test_const_get_if() {
+ {
+ using V = std::variant<int>;
+ constexpr const V *v = nullptr;
+ static_assert(std::get_if<0>(v) == nullptr, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42);
+ ASSERT_NOEXCEPT(std::get_if<0>(&v));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), const int *);
+ static_assert(*std::get_if<0>(&v) == 42, "");
+ static_assert(std::get_if<1>(&v) == nullptr, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), const long *);
+ static_assert(*std::get_if<1>(&v) == 42, "");
+ static_assert(std::get_if<0>(&v) == nullptr, "");
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), const int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+#endif
+}
+
+void test_get_if() {
+ {
+ using V = std::variant<int>;
+ V *v = nullptr;
+ assert(std::get_if<0>(v) == nullptr);
+ }
+ {
+ using V = std::variant<int, long>;
+ V v(42);
+ ASSERT_NOEXCEPT(std::get_if<0>(&v));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int *);
+ assert(*std::get_if<0>(&v) == 42);
+ assert(std::get_if<1>(&v) == nullptr);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), const long *);
+ assert(*std::get_if<1>(&v) == 42);
+ assert(std::get_if<0>(&v) == nullptr);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), const int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), const int *);
+ assert(std::get_if<0>(&v) == &x);
+ }
+#endif
+}
+
+int main() {
+ test_const_get_if();
+ test_get_if();
+}
diff --git a/test/std/utilities/variant/variant.get/get_if_type.pass.cpp b/test/std/utilities/variant/variant.get/get_if_type.pass.cpp
new file mode 100644
index 000000000000..a8cc664ef113
--- /dev/null
+++ b/test/std/utilities/variant/variant.get/get_if_type.pass.cpp
@@ -0,0 +1,130 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class T, class... Types>
+// constexpr add_pointer_t<T> get_if(variant<Types...>* v) noexcept;
+// template <class T, class... Types>
+// constexpr add_pointer_t<const T> get_if(const variant<Types...>* v)
+// noexcept;
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include <cassert>
+#include <variant>
+
+void test_const_get_if() {
+ {
+ using V = std::variant<int>;
+ constexpr const V *v = nullptr;
+ static_assert(std::get_if<int>(v) == nullptr, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42);
+ ASSERT_NOEXCEPT(std::get_if<int>(&v));
+ ASSERT_SAME_TYPE(decltype(std::get_if<int>(&v)), const int *);
+ static_assert(*std::get_if<int>(&v) == 42, "");
+ static_assert(std::get_if<const long>(&v) == nullptr, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get_if<const long>(&v)), const long *);
+ static_assert(*std::get_if<const long>(&v) == 42, "");
+ static_assert(std::get_if<int>(&v) == nullptr, "");
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<int &>(&v)), int *);
+ assert(std::get_if<int &>(&v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<int &&>(&v)), int *);
+ assert(std::get_if<int &&>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<const int &&>(&v)), const int *);
+ assert(std::get_if<const int &&>(&v) == &x);
+ }
+#endif
+}
+
+void test_get_if() {
+ {
+ using V = std::variant<int>;
+ V *v = nullptr;
+ assert(std::get_if<int>(v) == nullptr);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42);
+ ASSERT_NOEXCEPT(std::get_if<int>(&v));
+ ASSERT_SAME_TYPE(decltype(std::get_if<int>(&v)), int *);
+ assert(*std::get_if<int>(&v) == 42);
+ assert(std::get_if<const long>(&v) == nullptr);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get_if<const long>(&v)), const long *);
+ assert(*std::get_if<const long>(&v) == 42);
+ assert(std::get_if<int>(&v) == nullptr);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<int &>(&v)), int *);
+ assert(std::get_if<int &>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get_if<const int &>(&v)), const int *);
+ assert(std::get_if<const int &>(&v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<int &&>(&v)), int *);
+ assert(std::get_if<int &&>(&v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get_if<const int &&>(&v)), const int *);
+ assert(std::get_if<const int &&>(&v) == &x);
+ }
+#endif
+}
+
+int main() {
+ test_const_get_if();
+ test_get_if();
+}
diff --git a/test/std/utilities/variant/variant.get/get_index.pass.cpp b/test/std/utilities/variant/variant.get/get_index.pass.cpp
new file mode 100644
index 000000000000..72d17b0ed971
--- /dev/null
+++ b/test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -0,0 +1,287 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <size_t I, class... Types>
+// constexpr variant_alternative_t<I, variant<Types...>>&
+// get(variant<Types...>& v);
+// template <size_t I, class... Types>
+// constexpr variant_alternative_t<I, variant<Types...>>&&
+// get(variant<Types...>&& v);
+// template <size_t I, class... Types>
+// constexpr variant_alternative_t<I, variant<Types...>> const& get(const
+// variant<Types...>& v);
+// template <size_t I, class... Types>
+// constexpr variant_alternative_t<I, variant<Types...>> const&& get(const
+// variant<Types...>&& v);
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+void test_const_lvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ ASSERT_NOEXCEPT(std::get<0>(v));
+#endif
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ assert(std::get<0>(v) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42l);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ ASSERT_NOEXCEPT(std::get<1>(v));
+#endif
+ ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42l);
+ ASSERT_NOT_NOEXCEPT(std::get<1>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
+ assert(std::get<1>(v) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ assert(&std::get<0>(v) == &x);
+ }
+#endif
+}
+
+void test_lvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
+ assert(std::get<0>(v) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
+ assert(std::get<1>(v) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ assert(&std::get<0>(v) == &x);
+ }
+#endif
+}
+
+void test_rvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
+ assert(std::get<0>(std::move(v)) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
+ assert(std::get<1>(std::move(v)) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
+ assert(&std::get<0>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
+ assert(&std::get<0>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
+ int &&xref = std::get<0>(std::move(v));
+ assert(&xref == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
+ const int &&xref = std::get<0>(std::move(v));
+ assert(&xref == &x);
+ }
+#endif
+}
+
+void test_const_rvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ const V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
+ assert(std::get<0>(std::move(v)) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
+ assert(std::get<1>(std::move(v)) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
+ assert(&std::get<0>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
+ assert(&std::get<0>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
+ int &&xref = std::get<0>(std::move(v));
+ assert(&xref == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
+ const int &&xref = std::get<0>(std::move(v));
+ assert(&xref == &x);
+ }
+#endif
+}
+
+template <std::size_t I> using Idx = std::integral_constant<size_t, I>;
+
+void test_throws_for_all_value_categories() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, long>;
+ V v0(42);
+ const V &cv0 = v0;
+ assert(v0.index() == 0);
+ V v1(42l);
+ const V &cv1 = v1;
+ assert(v1.index() == 1);
+ std::integral_constant<size_t, 0> zero;
+ std::integral_constant<size_t, 1> one;
+ auto test = [](auto idx, auto &&v) {
+ using Idx = decltype(idx);
+ try {
+ std::get<Idx::value>(std::forward<decltype(v)>(v));
+ } catch (const std::bad_variant_access &) {
+ return true;
+ } catch (...) { /* ... */
+ }
+ return false;
+ };
+ { // lvalue test cases
+ assert(test(one, v0));
+ assert(test(zero, v1));
+ }
+ { // const lvalue test cases
+ assert(test(one, cv0));
+ assert(test(zero, cv1));
+ }
+ { // rvalue test cases
+ assert(test(one, std::move(v0)));
+ assert(test(zero, std::move(v1)));
+ }
+ { // const rvalue test cases
+ assert(test(one, std::move(cv0)));
+ assert(test(zero, std::move(cv1)));
+ }
+#endif
+}
+
+int main() {
+ test_const_lvalue_get();
+ test_lvalue_get();
+ test_rvalue_get();
+ test_const_rvalue_get();
+ test_throws_for_all_value_categories();
+}
diff --git a/test/std/utilities/variant/variant.get/get_type.pass.cpp b/test/std/utilities/variant/variant.get/get_type.pass.cpp
new file mode 100644
index 000000000000..fc355378a21a
--- /dev/null
+++ b/test/std/utilities/variant/variant.get/get_type.pass.cpp
@@ -0,0 +1,287 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class T, class... Types> constexpr T& get(variant<Types...>& v);
+// template <class T, class... Types> constexpr T&& get(variant<Types...>&& v);
+// template <class T, class... Types> constexpr const T& get(const
+// variant<Types...>& v);
+// template <class T, class... Types> constexpr const T&& get(const
+// variant<Types...>&& v);
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+void test_const_lvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ ASSERT_NOEXCEPT(std::get<int>(v));
+#endif
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ static_assert(std::get<int>(v) == 42, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<int>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
+ assert(std::get<int>(v) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ constexpr V v(42l);
+#ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
+ ASSERT_NOEXCEPT(std::get<const long>(v));
+#endif
+ ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
+ static_assert(std::get<const long>(v) == 42, "");
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42l);
+ ASSERT_NOT_NOEXCEPT(std::get<const long>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
+ assert(std::get<const long>(v) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<int &>(v)), int &);
+ assert(&std::get<int &>(v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<int &&>(v)), int &);
+ assert(&std::get<int &&>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<const int &&>(v)), const int &);
+ assert(&std::get<const int &&>(v) == &x);
+ }
+#endif
+}
+
+void test_lvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<int>(v));
+ ASSERT_SAME_TYPE(decltype(std::get<int>(v)), int &);
+ assert(std::get<int>(v) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
+ assert(std::get<const long>(v) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<int &>(v)), int &);
+ assert(&std::get<int &>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<const int &>(v)), const int &);
+ assert(&std::get<const int &>(v) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<int &&>(v)), int &);
+ assert(&std::get<int &&>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<const int &&>(v)), const int &);
+ assert(&std::get<const int &&>(v) == &x);
+ }
+#endif
+}
+
+void test_rvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<int>(std::move(v)));
+ ASSERT_SAME_TYPE(decltype(std::get<int>(std::move(v))), int &&);
+ assert(std::get<int>(std::move(v)) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
+ const long &&);
+ assert(std::get<const long>(std::move(v)) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<int &>(std::move(v))), int &);
+ assert(&std::get<int &>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<const int &>(std::move(v))),
+ const int &);
+ assert(&std::get<const int &>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<int &&>(std::move(v))), int &&);
+ int &&xref = std::get<int &&>(std::move(v));
+ assert(&xref == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<const int &&>(std::move(v))),
+ const int &&);
+ const int &&xref = std::get<const int &&>(std::move(v));
+ assert(&xref == &x);
+ }
+#endif
+}
+
+void test_const_rvalue_get() {
+ {
+ using V = std::variant<int, const long>;
+ const V v(42);
+ ASSERT_NOT_NOEXCEPT(std::get<int>(std::move(v)));
+ ASSERT_SAME_TYPE(decltype(std::get<int>(std::move(v))), const int &&);
+ assert(std::get<int>(std::move(v)) == 42);
+ }
+ {
+ using V = std::variant<int, const long>;
+ const V v(42l);
+ ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
+ const long &&);
+ assert(std::get<const long>(std::move(v)) == 42);
+ }
+// FIXME: Remove these once reference support is reinstated
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<int &>(std::move(v))), int &);
+ assert(&std::get<int &>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<const int &>;
+ int x = 42;
+ const V v(x);
+ ASSERT_SAME_TYPE(decltype(std::get<const int &>(std::move(v))),
+ const int &);
+ assert(&std::get<const int &>(std::move(v)) == &x);
+ }
+ {
+ using V = std::variant<int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<int &&>(std::move(v))), int &&);
+ int &&xref = std::get<int &&>(std::move(v));
+ assert(&xref == &x);
+ }
+ {
+ using V = std::variant<const int &&>;
+ int x = 42;
+ const V v(std::move(x));
+ ASSERT_SAME_TYPE(decltype(std::get<const int &&>(std::move(v))),
+ const int &&);
+ const int &&xref = std::get<const int &&>(std::move(v));
+ assert(&xref == &x);
+ }
+#endif
+}
+
+template <class Tp> struct identity { using type = Tp; };
+
+void test_throws_for_all_value_categories() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, long>;
+ V v0(42);
+ const V &cv0 = v0;
+ assert(v0.index() == 0);
+ V v1(42l);
+ const V &cv1 = v1;
+ assert(v1.index() == 1);
+ identity<int> zero;
+ identity<long> one;
+ auto test = [](auto idx, auto &&v) {
+ using Idx = decltype(idx);
+ try {
+ std::get<typename Idx::type>(std::forward<decltype(v)>(v));
+ } catch (const std::bad_variant_access &) {
+ return true;
+ } catch (...) { /* ... */
+ }
+ return false;
+ };
+ { // lvalue test cases
+ assert(test(one, v0));
+ assert(test(zero, v1));
+ }
+ { // const lvalue test cases
+ assert(test(one, cv0));
+ assert(test(zero, cv1));
+ }
+ { // rvalue test cases
+ assert(test(one, std::move(v0)));
+ assert(test(zero, std::move(v1)));
+ }
+ { // const rvalue test cases
+ assert(test(one, std::move(cv0)));
+ assert(test(zero, std::move(cv1)));
+ }
+#endif
+}
+
+int main() {
+ test_const_lvalue_get();
+ test_lvalue_get();
+ test_rvalue_get();
+ test_const_rvalue_get();
+ test_throws_for_all_value_categories();
+}
diff --git a/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp b/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp
new file mode 100644
index 000000000000..103b0498197d
--- /dev/null
+++ b/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp
@@ -0,0 +1,38 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class T, class... Types>
+// constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
+
+#include "test_macros.h"
+#include <variant>
+
+int main() {
+ {
+ using V = std::variant<int>;
+ constexpr V v;
+ static_assert(std::holds_alternative<int>(v), "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v;
+ static_assert(std::holds_alternative<int>(v), "");
+ static_assert(!std::holds_alternative<long>(v), "");
+ }
+ { // noexcept test
+ using V = std::variant<int>;
+ const V v;
+ ASSERT_NOEXCEPT(std::holds_alternative<int>(v));
+ }
+}
diff --git a/test/std/utilities/variant/variant.hash/hash.pass.cpp b/test/std/utilities/variant/variant.hash/hash.pass.cpp
new file mode 100644
index 000000000000..d807a7c7e2ea
--- /dev/null
+++ b/test/std/utilities/variant/variant.hash/hash.pass.cpp
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class... Types> struct hash<variant<Types...>>;
+// template <> struct hash<monostate>;
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+namespace std {
+template <> struct hash<::MakeEmptyT> {
+ size_t operator()(const ::MakeEmptyT &) const {
+ assert(false);
+ return 0;
+ }
+};
+}
+#endif
+
+void test_hash_variant() {
+ {
+ using V = std::variant<int, long, int>;
+ using H = std::hash<V>;
+ const V v(std::in_place_index<0>, 42);
+ const V v_copy = v;
+ V v2(std::in_place_index<0>, 100);
+ const H h{};
+ assert(h(v) == h(v));
+ assert(h(v) != h(v2));
+ assert(h(v) == h(v_copy));
+ {
+ ASSERT_SAME_TYPE(decltype(h(v)), std::size_t);
+ static_assert(std::is_copy_constructible<H>::value, "");
+ }
+ }
+ {
+ using V = std::variant<std::monostate, int, long, const char *>;
+ using H = std::hash<V>;
+ const char *str = "hello";
+ const V v0;
+ const V v0_other;
+ const V v1(42);
+ const V v1_other(100);
+ V v2(100l);
+ V v2_other(999l);
+ V v3(str);
+ V v3_other("not hello");
+ const H h{};
+ assert(h(v0) == h(v0));
+ assert(h(v0) == h(v0_other));
+ assert(h(v1) == h(v1));
+ assert(h(v1) != h(v1_other));
+ assert(h(v2) == h(v2));
+ assert(h(v2) != h(v2_other));
+ assert(h(v3) == h(v3));
+ assert(h(v3) != h(v3_other));
+ assert(h(v0) != h(v1));
+ assert(h(v0) != h(v2));
+ assert(h(v0) != h(v3));
+ assert(h(v1) != h(v2));
+ assert(h(v1) != h(v3));
+ assert(h(v2) != h(v3));
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ using H = std::hash<V>;
+ V v;
+ makeEmpty(v);
+ V v2;
+ makeEmpty(v2);
+ const H h{};
+ assert(h(v) == h(v2));
+ }
+#endif
+}
+
+void test_hash_monostate() {
+ using H = std::hash<std::monostate>;
+ const H h{};
+ std::monostate m1{};
+ const std::monostate m2{};
+ assert(h(m1) == h(m1));
+ assert(h(m2) == h(m2));
+ assert(h(m1) == h(m2));
+ {
+ ASSERT_SAME_TYPE(decltype(h(m1)), std::size_t);
+ static_assert(std::is_copy_constructible<H>::value, "");
+ }
+}
+
+void test_hash_variant_duplicate_elements() {
+ // Test that the index of the alternative participates in the hash value.
+ using V = std::variant<std::monostate, std::monostate>;
+ using H = std::hash<V>;
+ H h{};
+ const V v1(std::in_place_index<0>);
+ const V v2(std::in_place_index<1>);
+ assert(h(v1) == h(v1));
+ assert(h(v2) == h(v2));
+ LIBCPP_ASSERT(h(v1) != h(v2));
+}
+
+int main() {
+ test_hash_variant();
+ test_hash_variant_duplicate_elements();
+ test_hash_monostate();
+}
diff --git a/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp b/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp
new file mode 100644
index 000000000000..84689a050391
--- /dev/null
+++ b/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <size_t I, class T> struct variant_alternative; // undefined
+// template <size_t I, class T> struct variant_alternative<I, const T>;
+// template <size_t I, class T> struct variant_alternative<I, volatile T>;
+// template <size_t I, class T> struct variant_alternative<I, const volatile T>;
+// template <size_t I, class T>
+// using variant_alternative_t = typename variant_alternative<I, T>::type;
+//
+// template <size_t I, class... Types>
+// struct variant_alternative<I, variant<Types...>>;
+
+#include <memory>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+template <class V, size_t I, class E> void test() {
+ static_assert(
+ std::is_same_v<typename std::variant_alternative<I, V>::type, E>, "");
+ static_assert(
+ std::is_same_v<typename std::variant_alternative<I, const V>::type,
+ const E>,
+ "");
+ static_assert(
+ std::is_same_v<typename std::variant_alternative<I, volatile V>::type,
+ volatile E>,
+ "");
+ static_assert(
+ std::is_same_v<
+ typename std::variant_alternative<I, const volatile V>::type,
+ const volatile E>,
+ "");
+ static_assert(std::is_same_v<std::variant_alternative_t<I, V>, E>, "");
+ static_assert(std::is_same_v<std::variant_alternative_t<I, const V>, const E>,
+ "");
+ static_assert(
+ std::is_same_v<std::variant_alternative_t<I, volatile V>, volatile E>,
+ "");
+ static_assert(std::is_same_v<std::variant_alternative_t<I, const volatile V>,
+ const volatile E>,
+ "");
+}
+
+int main() {
+ {
+ using V = std::variant<int, void *, const void *, long double>;
+ test<V, 0, int>();
+ test<V, 1, void *>();
+ test<V, 2, const void *>();
+ test<V, 3, long double>();
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, int &, const int &, int &&, long double>;
+ test<V, 0, int>();
+ test<V, 1, int &>();
+ test<V, 2, const int &>();
+ test<V, 3, int &&>();
+ test<V, 4, long double>();
+ }
+#endif
+}
diff --git a/test/std/utilities/variant/variant.helpers/variant_size.pass.cpp b/test/std/utilities/variant/variant.helpers/variant_size.pass.cpp
new file mode 100644
index 000000000000..2085fa56effe
--- /dev/null
+++ b/test/std/utilities/variant/variant.helpers/variant_size.pass.cpp
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class T> struct variant_size; // undefined
+// template <class T> struct variant_size<const T>;
+// template <class T> struct variant_size<volatile T>;
+// template <class T> struct variant_size<const volatile T>;
+// template <class T> constexpr size_t variant_size_v
+// = variant_size<T>::value;
+
+#include <memory>
+#include <type_traits>
+#include <variant>
+
+template <class V, size_t E> void test() {
+ static_assert(std::variant_size<V>::value == E, "");
+ static_assert(std::variant_size<const V>::value == E, "");
+ static_assert(std::variant_size<volatile V>::value == E, "");
+ static_assert(std::variant_size<const volatile V>::value == E, "");
+ static_assert(std::variant_size_v<V> == E, "");
+ static_assert(std::variant_size_v<const V> == E, "");
+ static_assert(std::variant_size_v<volatile V> == E, "");
+ static_assert(std::variant_size_v<const volatile V> == E, "");
+ static_assert(std::is_base_of<std::integral_constant<std::size_t, E>,
+ std::variant_size<V>>::value,
+ "");
+};
+
+int main() {
+ test<std::variant<>, 0>();
+ test<std::variant<void *>, 1>();
+ test<std::variant<long, long, void *, double>, 4>();
+}
diff --git a/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp b/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp
new file mode 100644
index 000000000000..49abba2954e5
--- /dev/null
+++ b/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// constexpr bool operator<(monostate, monostate) noexcept { return false; }
+// constexpr bool operator>(monostate, monostate) noexcept { return false; }
+// constexpr bool operator<=(monostate, monostate) noexcept { return true; }
+// constexpr bool operator>=(monostate, monostate) noexcept { return true; }
+// constexpr bool operator==(monostate, monostate) noexcept { return true; }
+// constexpr bool operator!=(monostate, monostate) noexcept { return false; }
+
+#include "test_macros.h"
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+int main() {
+ using M = std::monostate;
+ constexpr M m1{};
+ constexpr M m2{};
+ {
+ static_assert((m1 < m2) == false, "");
+ ASSERT_NOEXCEPT(m1 < m2);
+ }
+ {
+ static_assert((m1 > m2) == false, "");
+ ASSERT_NOEXCEPT(m1 > m2);
+ }
+ {
+ static_assert((m1 <= m2) == true, "");
+ ASSERT_NOEXCEPT(m1 <= m2);
+ }
+ {
+ static_assert((m1 >= m2) == true, "");
+ ASSERT_NOEXCEPT(m1 >= m2);
+ }
+ {
+ static_assert((m1 == m2) == true, "");
+ ASSERT_NOEXCEPT(m1 == m2);
+ }
+ {
+ static_assert((m1 != m2) == false, "");
+ ASSERT_NOEXCEPT(m1 != m2);
+ }
+}
diff --git a/test/std/utilities/variant/variant.monostate/monostate.pass.cpp b/test/std/utilities/variant/variant.monostate/monostate.pass.cpp
new file mode 100644
index 000000000000..76cddf90043d
--- /dev/null
+++ b/test/std/utilities/variant/variant.monostate/monostate.pass.cpp
@@ -0,0 +1,28 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// struct monostate {};
+
+#include <type_traits>
+#include <variant>
+
+int main() {
+ using M = std::monostate;
+ static_assert(std::is_trivially_default_constructible<M>::value, "");
+ static_assert(std::is_trivially_copy_constructible<M>::value, "");
+ static_assert(std::is_trivially_copy_assignable<M>::value, "");
+ static_assert(std::is_trivially_destructible<M>::value, "");
+ constexpr M m{};
+ ((void)m);
+}
diff --git a/test/std/utilities/variant/variant.relops/relops.pass.cpp b/test/std/utilities/variant/variant.relops/relops.pass.cpp
new file mode 100644
index 000000000000..4337b4bdbbd7
--- /dev/null
+++ b/test/std/utilities/variant/variant.relops/relops.pass.cpp
@@ -0,0 +1,227 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types>
+// constexpr bool
+// operator==(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator<(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator>(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;
+//
+// template <class ...Types>
+// constexpr bool
+// operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct MakeEmptyT {
+ MakeEmptyT() = default;
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+};
+inline bool operator==(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+inline bool operator!=(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+inline bool operator<(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+inline bool operator<=(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+inline bool operator>(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+inline bool operator>=(const MakeEmptyT &, const MakeEmptyT &) {
+ assert(false);
+ return false;
+}
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = std::move(v2);
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_equality() {
+ {
+ using V = std::variant<int, long>;
+ constexpr V v1(42);
+ constexpr V v2(42);
+ static_assert(v1 == v2, "");
+ static_assert(v2 == v1, "");
+ static_assert(!(v1 != v2), "");
+ static_assert(!(v2 != v1), "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v1(42);
+ constexpr V v2(43);
+ static_assert(!(v1 == v2), "");
+ static_assert(!(v2 == v1), "");
+ static_assert(v1 != v2, "");
+ static_assert(v2 != v1, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v1(42);
+ constexpr V v2(42l);
+ static_assert(!(v1 == v2), "");
+ static_assert(!(v2 == v1), "");
+ static_assert(v1 != v2, "");
+ static_assert(v2 != v1, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v1(42l);
+ constexpr V v2(42l);
+ static_assert(v1 == v2, "");
+ static_assert(v2 == v1, "");
+ static_assert(!(v1 != v2), "");
+ static_assert(!(v2 != v1), "");
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ V v2;
+ makeEmpty(v2);
+ assert(!(v1 == v2));
+ assert(!(v2 == v1));
+ assert(v1 != v2);
+ assert(v2 != v1);
+ }
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v2;
+ assert(!(v1 == v2));
+ assert(!(v2 == v1));
+ assert(v1 != v2);
+ assert(v2 != v1);
+ }
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v2;
+ makeEmpty(v2);
+ assert(v1 == v2);
+ assert(v2 == v1);
+ assert(!(v1 != v2));
+ assert(!(v2 != v1));
+ }
+#endif
+}
+
+template <class Var>
+constexpr bool test_less(const Var &l, const Var &r, bool expect_less,
+ bool expect_greater) {
+ return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&
+ ((l > r) == expect_greater) && (!(l <= r) == expect_greater);
+}
+
+void test_relational() {
+ { // same index, same value
+ using V = std::variant<int, long>;
+ constexpr V v1(1);
+ constexpr V v2(1);
+ static_assert(test_less(v1, v2, false, false), "");
+ }
+ { // same index, value < other_value
+ using V = std::variant<int, long>;
+ constexpr V v1(0);
+ constexpr V v2(1);
+ static_assert(test_less(v1, v2, true, false), "");
+ }
+ { // same index, value > other_value
+ using V = std::variant<int, long>;
+ constexpr V v1(1);
+ constexpr V v2(0);
+ static_assert(test_less(v1, v2, false, true), "");
+ }
+ { // LHS.index() < RHS.index()
+ using V = std::variant<int, long>;
+ constexpr V v1(0);
+ constexpr V v2(0l);
+ static_assert(test_less(v1, v2, true, false), "");
+ }
+ { // LHS.index() > RHS.index()
+ using V = std::variant<int, long>;
+ constexpr V v1(0l);
+ constexpr V v2(0);
+ static_assert(test_less(v1, v2, false, true), "");
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // LHS.index() < RHS.index(), RHS is empty
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ V v2;
+ makeEmpty(v2);
+ assert(test_less(v1, v2, false, true));
+ }
+ { // LHS.index() > RHS.index(), LHS is empty
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v2;
+ assert(test_less(v1, v2, true, false));
+ }
+ { // LHS.index() == RHS.index(), LHS and RHS are empty
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v2;
+ makeEmpty(v2);
+ assert(test_less(v1, v2, false, false));
+ }
+#endif
+}
+
+int main() {
+ test_equality();
+ test_relational();
+}
diff --git a/test/std/utilities/utility/forward/forward4.fail.cpp b/test/std/utilities/variant/variant.synopsis/variant_npos.pass.cpp
index 276506f811b5..4d7c8563caad 100644
--- a/test/std/utilities/utility/forward/forward4.fail.cpp
+++ b/test/std/utilities/variant/variant.synopsis/variant_npos.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -7,19 +8,14 @@
//
//===----------------------------------------------------------------------===//
-// test forward
+// UNSUPPORTED: c++98, c++03, c++11, c++14
-#include <utility>
+// <variant>
-struct A
-{
-};
+// constexpr size_t variant_npos = -1;
-A source() {return A();}
-const A csource() {return A();}
+#include <variant>
-int main()
-{
- const A ca = A();
- std::forward<A>(ca); // error
+int main() {
+ static_assert(std::variant_npos == static_cast<std::size_t>(-1), "");
}
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
new file mode 100644
index 000000000000..10022b14aa06
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -0,0 +1,232 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class T>
+// variant& operator=(T&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+namespace MetaHelpers {
+
+struct Dummy {
+ Dummy() = default;
+};
+
+struct ThrowsCtorT {
+ ThrowsCtorT(int) noexcept(false) {}
+ ThrowsCtorT &operator=(int) noexcept { return *this; }
+};
+
+struct ThrowsAssignT {
+ ThrowsAssignT(int) noexcept {}
+ ThrowsAssignT &operator=(int) noexcept(false) { return *this; }
+};
+
+struct NoThrowT {
+ NoThrowT(int) noexcept {}
+ NoThrowT &operator=(int) noexcept { return *this; }
+};
+
+} // namespace MetaHelpers
+
+namespace RuntimeHelpers {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+struct ThrowsCtorT {
+ int value;
+ ThrowsCtorT() : value(0) {}
+ ThrowsCtorT(int) noexcept(false) { throw 42; }
+ ThrowsCtorT &operator=(int v) noexcept {
+ value = v;
+ return *this;
+ }
+};
+
+struct ThrowsAssignT {
+ int value;
+ ThrowsAssignT() : value(0) {}
+ ThrowsAssignT(int v) noexcept : value(v) {}
+ ThrowsAssignT &operator=(int) noexcept(false) { throw 42; }
+};
+
+struct NoThrowT {
+ int value;
+ NoThrowT() : value(0) {}
+ NoThrowT(int v) noexcept : value(v) {}
+ NoThrowT &operator=(int v) noexcept {
+ value = v;
+ return *this;
+ }
+};
+
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+} // namespace RuntimeHelpers
+
+void test_T_assignment_noexcept() {
+ using namespace MetaHelpers;
+ {
+ using V = std::variant<Dummy, NoThrowT>;
+ static_assert(std::is_nothrow_assignable<V, int>::value, "");
+ }
+ {
+ using V = std::variant<Dummy, ThrowsCtorT>;
+ static_assert(!std::is_nothrow_assignable<V, int>::value, "");
+ }
+ {
+ using V = std::variant<Dummy, ThrowsAssignT>;
+ static_assert(!std::is_nothrow_assignable<V, int>::value, "");
+ }
+}
+
+void test_T_assignment_sfinae() {
+ {
+ using V = std::variant<long, unsigned>;
+ static_assert(!std::is_assignable<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, std::string>;
+ static_assert(!std::is_assignable<V, const char *>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, void *>;
+ static_assert(!std::is_assignable<V, int>::value, "no matching operator=");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, int &&>;
+ static_assert(!std::is_assignable<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<int, const int &>;
+ static_assert(!std::is_assignable<V, int>::value, "ambiguous");
+ }
+#endif
+}
+
+void test_T_assignment_basic() {
+ {
+ std::variant<int> v(43);
+ v = 42;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 42);
+ }
+ {
+ std::variant<int, long> v(43l);
+ v = 42;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 42);
+ v = 43l;
+ assert(v.index() == 1);
+ assert(std::get<1>(v) == 43);
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &, int &&, long>;
+ int x = 42;
+ V v(43l);
+ v = x;
+ assert(v.index() == 0);
+ assert(&std::get<0>(v) == &x);
+ v = std::move(x);
+ assert(v.index() == 1);
+ assert(&std::get<1>(v) == &x);
+ // 'long' is selected by FUN(const int &) since 'const int &' cannot bind
+ // to 'int&'.
+ const int &cx = x;
+ v = cx;
+ assert(v.index() == 2);
+ assert(std::get<2>(v) == 42);
+ }
+#endif
+}
+
+void test_T_assignment_performs_construction() {
+ using namespace RuntimeHelpers;
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<std::string, ThrowsCtorT>;
+ V v(std::in_place_type<std::string>, "hello");
+ try {
+ v = 42;
+ } catch (...) { /* ... */
+ }
+ assert(v.valueless_by_exception());
+ }
+ {
+ using V = std::variant<ThrowsAssignT, std::string>;
+ V v(std::in_place_type<std::string>, "hello");
+ v = 42;
+ assert(v.index() == 0);
+ assert(std::get<0>(v).value == 42);
+ }
+#endif
+}
+
+void test_T_assignment_performs_assignment() {
+ using namespace RuntimeHelpers;
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<ThrowsCtorT>;
+ V v;
+ v = 42;
+ assert(v.index() == 0);
+ assert(std::get<0>(v).value == 42);
+ }
+ {
+ using V = std::variant<ThrowsCtorT, std::string>;
+ V v;
+ v = 42;
+ assert(v.index() == 0);
+ assert(std::get<0>(v).value == 42);
+ }
+ {
+ using V = std::variant<ThrowsAssignT>;
+ V v(100);
+ try {
+ v = 42;
+ assert(false);
+ } catch (...) { /* ... */
+ }
+ assert(v.index() == 0);
+ assert(std::get<0>(v).value == 100);
+ }
+ {
+ using V = std::variant<std::string, ThrowsAssignT>;
+ V v(100);
+ try {
+ v = 42;
+ assert(false);
+ } catch (...) { /* ... */
+ }
+ assert(v.index() == 1);
+ assert(std::get<1>(v).value == 100);
+ }
+#endif
+}
+
+int main() {
+ test_T_assignment_basic();
+ test_T_assignment_performs_construction();
+ test_T_assignment_performs_assignment();
+ test_T_assignment_noexcept();
+ test_T_assignment_sfinae();
+}
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
new file mode 100644
index 000000000000..d92f16fd6418
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
@@ -0,0 +1,397 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant& operator=(variant const&);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct NoCopy {
+ NoCopy(const NoCopy &) = delete;
+ NoCopy &operator=(const NoCopy &) = default;
+};
+
+struct NothrowCopy {
+ NothrowCopy(const NothrowCopy &) noexcept = default;
+ NothrowCopy &operator=(const NothrowCopy &) noexcept = default;
+};
+
+struct CopyOnly {
+ CopyOnly(const CopyOnly &) = default;
+ CopyOnly(CopyOnly &&) = delete;
+ CopyOnly &operator=(const CopyOnly &) = default;
+ CopyOnly &operator=(CopyOnly &&) = delete;
+};
+
+struct MoveOnly {
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+ MoveOnly &operator=(const MoveOnly &) = default;
+};
+
+struct MoveOnlyNT {
+ MoveOnlyNT(const MoveOnlyNT &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&) {}
+ MoveOnlyNT &operator=(const MoveOnlyNT &) = default;
+};
+
+struct CopyAssign {
+ static int alive;
+ static int copy_construct;
+ static int copy_assign;
+ static int move_construct;
+ static int move_assign;
+ static void reset() {
+ copy_construct = copy_assign = move_construct = move_assign = alive = 0;
+ }
+ CopyAssign(int v) : value(v) { ++alive; }
+ CopyAssign(const CopyAssign &o) : value(o.value) {
+ ++alive;
+ ++copy_construct;
+ }
+ CopyAssign(CopyAssign &&o) : value(o.value) {
+ o.value = -1;
+ ++alive;
+ ++move_construct;
+ }
+ CopyAssign &operator=(const CopyAssign &o) {
+ value = o.value;
+ ++copy_assign;
+ return *this;
+ }
+ CopyAssign &operator=(CopyAssign &&o) {
+ value = o.value;
+ o.value = -1;
+ ++move_assign;
+ return *this;
+ }
+ ~CopyAssign() { --alive; }
+ int value;
+};
+
+int CopyAssign::alive = 0;
+int CopyAssign::copy_construct = 0;
+int CopyAssign::copy_assign = 0;
+int CopyAssign::move_construct = 0;
+int CopyAssign::move_assign = 0;
+
+struct CopyMaybeThrows {
+ CopyMaybeThrows(const CopyMaybeThrows &);
+ CopyMaybeThrows &operator=(const CopyMaybeThrows &);
+};
+struct CopyDoesThrow {
+ CopyDoesThrow(const CopyDoesThrow &) noexcept(false);
+ CopyDoesThrow &operator=(const CopyDoesThrow &) noexcept(false);
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct CopyThrows {
+ CopyThrows() = default;
+ CopyThrows(const CopyThrows &) { throw 42; }
+ CopyThrows &operator=(const CopyThrows &) { throw 42; }
+};
+
+struct MoveThrows {
+ static int alive;
+ MoveThrows() { ++alive; }
+ MoveThrows(const MoveThrows &) { ++alive; }
+ MoveThrows(MoveThrows &&) { throw 42; }
+ MoveThrows &operator=(const MoveThrows &) { return *this; }
+ MoveThrows &operator=(MoveThrows &&) { throw 42; }
+ ~MoveThrows() { --alive; }
+};
+
+int MoveThrows::alive = 0;
+
+struct MakeEmptyT {
+ static int alive;
+ MakeEmptyT() { ++alive; }
+ MakeEmptyT(const MakeEmptyT &) {
+ ++alive;
+ // Don't throw from the copy constructor since variant's assignment
+ // operator performs a copy before committing to the assignment.
+ }
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+ ~MakeEmptyT() { --alive; }
+};
+
+int MakeEmptyT::alive = 0;
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = v2;
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_copy_assignment_not_noexcept() {
+ {
+ using V = std::variant<CopyMaybeThrows>;
+ static_assert(!std::is_nothrow_copy_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, CopyDoesThrow>;
+ static_assert(!std::is_nothrow_copy_assignable<V>::value, "");
+ }
+}
+
+void test_copy_assignment_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_copy_assignable<V>::value, "");
+ }
+ {
+ // variant only provides copy assignment when both the copy and move
+ // constructors are well formed
+ using V = std::variant<int, CopyOnly>;
+ static_assert(!std::is_copy_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_copy_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(!std::is_copy_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(!std::is_copy_assignable<V>::value, "");
+ }
+}
+
+void test_copy_assignment_empty_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, long, MET>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+#endif
+}
+
+void test_copy_assignment_non_empty_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET>;
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_index<2>, "hello");
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+#endif
+}
+
+void test_copy_assignment_empty_non_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_index<0>, 42);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 0);
+ assert(std::get<0>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_type<std::string>, "hello");
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ }
+#endif
+}
+
+void test_copy_assignment_same_index() {
+ {
+ using V = std::variant<int>;
+ V v1(43);
+ V v2(42);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 0);
+ assert(std::get<0>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, long, unsigned>;
+ V v1(43l);
+ V v2(42l);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, CopyAssign, unsigned>;
+ V v1(std::in_place_type<CopyAssign>, 43);
+ V v2(std::in_place_type<CopyAssign>, 42);
+ CopyAssign::reset();
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1).value == 42);
+ assert(CopyAssign::copy_construct == 0);
+ assert(CopyAssign::move_construct == 0);
+ assert(CopyAssign::copy_assign == 1);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_type<MET>);
+ MET &mref = std::get<1>(v1);
+ V v2(std::in_place_type<MET>);
+ try {
+ v1 = v2;
+ assert(false);
+ } catch (...) {
+ }
+ assert(v1.index() == 1);
+ assert(&std::get<1>(v1) == &mref);
+ }
+#endif
+}
+
+void test_copy_assignment_different_index() {
+ {
+ using V = std::variant<int, long, unsigned>;
+ V v1(43);
+ V v2(42l);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, CopyAssign, unsigned>;
+ CopyAssign::reset();
+ V v1(std::in_place_type<unsigned>, 43);
+ V v2(std::in_place_type<CopyAssign>, 42);
+ assert(CopyAssign::copy_construct == 0);
+ assert(CopyAssign::move_construct == 0);
+ assert(CopyAssign::alive == 1);
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1).value == 42);
+ assert(CopyAssign::alive == 2);
+ assert(CopyAssign::copy_construct == 1);
+ assert(CopyAssign::move_construct == 1);
+ assert(CopyAssign::copy_assign == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ // Test that if copy construction throws then original value is
+ // unchanged.
+ using V = std::variant<int, CopyThrows, std::string>;
+ V v1(std::in_place_type<std::string>, "hello");
+ V v2(std::in_place_type<CopyThrows>);
+ try {
+ v1 = v2;
+ assert(false);
+ } catch (...) { /* ... */
+ }
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ }
+ {
+ // Test that if move construction throws then the variant is left
+ // valueless by exception.
+ using V = std::variant<int, MoveThrows, std::string>;
+ V v1(std::in_place_type<std::string>, "hello");
+ V v2(std::in_place_type<MoveThrows>);
+ assert(MoveThrows::alive == 1);
+ try {
+ v1 = v2;
+ assert(false);
+ } catch (...) { /* ... */
+ }
+ assert(v1.valueless_by_exception());
+ assert(v2.index() == 1);
+ assert(MoveThrows::alive == 1);
+ }
+ {
+ using V = std::variant<int, CopyThrows, std::string>;
+ V v1(std::in_place_type<CopyThrows>);
+ V v2(std::in_place_type<std::string>, "hello");
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ assert(v2.index() == 2);
+ assert(std::get<2>(v2) == "hello");
+ }
+ {
+ using V = std::variant<int, MoveThrows, std::string>;
+ V v1(std::in_place_type<MoveThrows>);
+ V v2(std::in_place_type<std::string>, "hello");
+ V &vref = (v1 = v2);
+ assert(&vref == &v1);
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ assert(v2.index() == 2);
+ assert(std::get<2>(v2) == "hello");
+ }
+#endif
+}
+
+
+int main() {
+ test_copy_assignment_empty_empty();
+ test_copy_assignment_non_empty_empty();
+ test_copy_assignment_empty_non_empty();
+ test_copy_assignment_same_index();
+ test_copy_assignment_different_index();
+ test_copy_assignment_sfinae();
+ test_copy_assignment_not_noexcept();
+}
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
new file mode 100644
index 000000000000..232d77c882eb
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
@@ -0,0 +1,319 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant& operator=(variant&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct NoCopy {
+ NoCopy(const NoCopy &) = delete;
+ NoCopy &operator=(const NoCopy &) = default;
+};
+
+struct CopyOnly {
+ CopyOnly(const CopyOnly &) = default;
+ CopyOnly(CopyOnly &&) = delete;
+ CopyOnly &operator=(const CopyOnly &) = default;
+ CopyOnly &operator=(CopyOnly &&) = delete;
+};
+
+struct MoveOnly {
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+ MoveOnly &operator=(const MoveOnly &) = delete;
+ MoveOnly &operator=(MoveOnly &&) = default;
+};
+
+struct MoveOnlyNT {
+ MoveOnlyNT(const MoveOnlyNT &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&) {}
+ MoveOnlyNT &operator=(const MoveOnlyNT &) = delete;
+ MoveOnlyNT &operator=(MoveOnlyNT &&) = default;
+};
+
+struct MoveOnlyOddNothrow {
+ MoveOnlyOddNothrow(MoveOnlyOddNothrow &&) noexcept(false) {}
+ MoveOnlyOddNothrow(const MoveOnlyOddNothrow &) = delete;
+ MoveOnlyOddNothrow &operator=(MoveOnlyOddNothrow &&) noexcept = default;
+ MoveOnlyOddNothrow &operator=(const MoveOnlyOddNothrow &) = delete;
+};
+
+struct MoveAssignOnly {
+ MoveAssignOnly(MoveAssignOnly &&) = delete;
+ MoveAssignOnly &operator=(MoveAssignOnly &&) = default;
+};
+
+struct MoveAssign {
+ static int move_construct;
+ static int move_assign;
+ static void reset() { move_construct = move_assign = 0; }
+ MoveAssign(int v) : value(v) {}
+ MoveAssign(MoveAssign &&o) : value(o.value) {
+ ++move_construct;
+ o.value = -1;
+ }
+ MoveAssign &operator=(MoveAssign &&o) {
+ value = o.value;
+ ++move_assign;
+ o.value = -1;
+ return *this;
+ }
+ int value;
+};
+
+int MoveAssign::move_construct = 0;
+int MoveAssign::move_assign = 0;
+
+void test_move_assignment_noexcept() {
+ {
+ using V = std::variant<int>;
+ static_assert(std::is_nothrow_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<MoveOnly>;
+ static_assert(std::is_nothrow_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_nothrow_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_nothrow_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<MoveOnlyNT>;
+ static_assert(!std::is_nothrow_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<MoveOnlyOddNothrow>;
+ static_assert(!std::is_nothrow_move_assignable<V>::value, "");
+ }
+}
+
+void test_move_assignment_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_move_assignable<V>::value, "");
+ }
+ {
+ // variant only provides move assignment when both the move constructor
+ // and move assignment operator are well formed.
+ using V = std::variant<int, CopyOnly>;
+ static_assert(!std::is_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_move_assignable<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(std::is_move_assignable<V>::value, "");
+ }
+ {
+ // variant only provides move assignment when the types also provide
+ // a move constructor.
+ using V = std::variant<int, MoveAssignOnly>;
+ static_assert(!std::is_move_assignable<V>::value, "");
+ }
+}
+
+void test_move_assignment_empty_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, long, MET>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+#endif
+}
+
+void test_move_assignment_non_empty_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET>;
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_index<2>, "hello");
+ V v2(std::in_place_index<0>);
+ makeEmpty(v2);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+#endif
+}
+
+void test_move_assignment_empty_non_empty() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_index<0>, 42);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 0);
+ assert(std::get<0>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_index<0>);
+ makeEmpty(v1);
+ V v2(std::in_place_type<std::string>, "hello");
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ }
+#endif
+}
+
+void test_move_assignment_same_index() {
+ {
+ using V = std::variant<int>;
+ V v1(43);
+ V v2(42);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 0);
+ assert(std::get<0>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, long, unsigned>;
+ V v1(43l);
+ V v2(42l);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, MoveAssign, unsigned>;
+ V v1(std::in_place_type<MoveAssign>, 43);
+ V v2(std::in_place_type<MoveAssign>, 42);
+ MoveAssign::reset();
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1).value == 42);
+ assert(MoveAssign::move_construct == 0);
+ assert(MoveAssign::move_assign == 1);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_type<MET>);
+ MET &mref = std::get<1>(v1);
+ V v2(std::in_place_type<MET>);
+ try {
+ v1 = std::move(v2);
+ assert(false);
+ } catch (...) {
+ }
+ assert(v1.index() == 1);
+ assert(&std::get<1>(v1) == &mref);
+ }
+#endif
+}
+
+void test_move_assignment_different_index() {
+ {
+ using V = std::variant<int, long, unsigned>;
+ V v1(43);
+ V v2(42l);
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1) == 42);
+ }
+ {
+ using V = std::variant<int, MoveAssign, unsigned>;
+ V v1(std::in_place_type<unsigned>, 43);
+ V v2(std::in_place_type<MoveAssign>, 42);
+ MoveAssign::reset();
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 1);
+ assert(std::get<1>(v1).value == 42);
+ assert(MoveAssign::move_construct == 1);
+ assert(MoveAssign::move_assign == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using MET = MakeEmptyT;
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_type<int>);
+ V v2(std::in_place_type<MET>);
+ try {
+ v1 = std::move(v2);
+ assert(false);
+ } catch (...) {
+ }
+ assert(v1.valueless_by_exception());
+ assert(v1.index() == std::variant_npos);
+ }
+ {
+ using V = std::variant<int, MET, std::string>;
+ V v1(std::in_place_type<MET>);
+ V v2(std::in_place_type<std::string>, "hello");
+ V &vref = (v1 = std::move(v2));
+ assert(&vref == &v1);
+ assert(v1.index() == 2);
+ assert(std::get<2>(v1) == "hello");
+ }
+#endif
+}
+
+int main() {
+ test_move_assignment_empty_empty();
+ test_move_assignment_non_empty_empty();
+ test_move_assignment_empty_non_empty();
+ test_move_assignment_same_index();
+ test_move_assignment_different_index();
+ test_move_assignment_sfinae();
+ test_move_assignment_noexcept();
+}
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
new file mode 100644
index 000000000000..d33ea0bd3f4e
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class T> constexpr variant(T&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct Dummy {
+ Dummy() = default;
+};
+
+struct ThrowsT {
+ ThrowsT(int) noexcept(false) {}
+};
+
+struct NoThrowT {
+ NoThrowT(int) noexcept(true) {}
+};
+
+void test_T_ctor_noexcept() {
+ {
+ using V = std::variant<Dummy, NoThrowT>;
+ static_assert(std::is_nothrow_constructible<V, int>::value, "");
+ }
+ {
+ using V = std::variant<Dummy, ThrowsT>;
+ static_assert(!std::is_nothrow_constructible<V, int>::value, "");
+ }
+}
+
+void test_T_ctor_sfinae() {
+ {
+ using V = std::variant<long, unsigned>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, std::string>;
+ static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, void *>;
+ static_assert(!std::is_constructible<V, int>::value,
+ "no matching constructor");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, int &&>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<int, const int &>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+#endif
+}
+
+void test_T_ctor_basic() {
+ {
+ constexpr std::variant<int> v(42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long> v(42l);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<const int &, int &&, long>;
+ static_assert(std::is_convertible<int &, V>::value, "must be implicit");
+ int x = 42;
+ V v(x);
+ assert(v.index() == 0);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<const int &, int &&, long>;
+ static_assert(std::is_convertible<int, V>::value, "must be implicit");
+ int x = 42;
+ V v(std::move(x));
+ assert(v.index() == 1);
+ assert(&std::get<1>(v) == &x);
+ }
+#endif
+}
+
+int main() {
+ test_T_ctor_basic();
+ test_T_ctor_noexcept();
+ test_T_ctor_sfinae();
+}
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
new file mode 100644
index 000000000000..18216c6da923
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -0,0 +1,159 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant(variant const&);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct NonT {
+ NonT(int v) : value(v) {}
+ NonT(const NonT &o) : value(o.value) {}
+ int value;
+};
+static_assert(!std::is_trivially_copy_constructible<NonT>::value, "");
+
+struct NoCopy {
+ NoCopy(const NoCopy &) = delete;
+};
+
+struct MoveOnly {
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+};
+
+struct MoveOnlyNT {
+ MoveOnlyNT(const MoveOnlyNT &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&) {}
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct MakeEmptyT {
+ static int alive;
+ MakeEmptyT() { ++alive; }
+ MakeEmptyT(const MakeEmptyT &) {
+ ++alive;
+ // Don't throw from the copy constructor since variant's assignment
+ // operator performs a copy before committing to the assignment.
+ }
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+ ~MakeEmptyT() { --alive; }
+};
+
+int MakeEmptyT::alive = 0;
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = v2;
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_copy_ctor_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+}
+
+void test_copy_ctor_basic() {
+ {
+ std::variant<int> v(std::in_place_index<0>, 42);
+ std::variant<int> v2 = v;
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2) == 42);
+ }
+ {
+ std::variant<int, long> v(std::in_place_index<1>, 42);
+ std::variant<int, long> v2 = v;
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2) == 42);
+ }
+ {
+ std::variant<NonT> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<NonT> v2(v);
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, NonT> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, NonT> v2(v);
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2).value == 42);
+ }
+}
+
+void test_copy_ctor_valueless_by_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ const V &cv1 = v1;
+ V v(cv1);
+ assert(v.valueless_by_exception());
+#endif
+}
+
+template <size_t Idx>
+constexpr bool test_constexpr_copy_ctor_extension_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() {
+#ifdef _LIBCPP_VERSION
+ using V = std::variant<long, void*, const int>;
+ static_assert(std::is_trivially_copyable<V>::value, "");
+ static_assert(std::is_trivially_copy_constructible<V>::value, "");
+ 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)), "");
+#endif
+}
+
+int main() {
+ test_copy_ctor_basic();
+ test_copy_ctor_valueless_by_exception();
+ test_copy_ctor_sfinae();
+ test_constexpr_copy_ctor_extension();
+}
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
new file mode 100644
index 000000000000..a4a86ff6c1ca
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// constexpr variant() noexcept(see below);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct NonDefaultConstructible {
+ NonDefaultConstructible(int) {}
+};
+
+struct NotNoexcept {
+ NotNoexcept() noexcept(false) {}
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct DefaultCtorThrows {
+ DefaultCtorThrows() { throw 42; }
+};
+#endif
+
+void test_default_ctor_sfinae() {
+ {
+ using V = std::variant<std::monostate, int>;
+ static_assert(std::is_default_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<NonDefaultConstructible, int>;
+ static_assert(!std::is_default_constructible<V>::value, "");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &, int>;
+ static_assert(!std::is_default_constructible<V>::value, "");
+ }
+#endif
+}
+
+void test_default_ctor_noexcept() {
+ {
+ using V = std::variant<int>;
+ static_assert(std::is_nothrow_default_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<NotNoexcept>;
+ static_assert(!std::is_nothrow_default_constructible<V>::value, "");
+ }
+}
+
+void test_default_ctor_throws() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<DefaultCtorThrows, int>;
+ try {
+ V v;
+ assert(false);
+ } catch (const int &ex) {
+ assert(ex == 42);
+ } catch (...) {
+ assert(false);
+ }
+#endif
+}
+
+void test_default_ctor_basic() {
+ {
+ std::variant<int> v;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 0);
+ }
+ {
+ std::variant<int, long> 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, "");
+ static_assert(std::get<0>(v) == 0, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v;
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 0, "");
+ }
+}
+
+int main() {
+ test_default_ctor_basic();
+ test_default_ctor_sfinae();
+ test_default_ctor_noexcept();
+ test_default_ctor_throws();
+}
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
new file mode 100644
index 000000000000..18115722f8d1
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class ...Args>
+// constexpr explicit variant(in_place_index_t<I>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+void test_ctor_sfinae() {
+ {
+ using V = std::variant<int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<0>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, long long>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<1>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<2>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<2>, int *>(), "");
+ }
+ { // args not convertible to type
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<0>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, int *>(), "");
+ }
+ { // index not in variant
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<3>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<3>, int>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<int> v(std::in_place_index<0>, 42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long, long> v(std::in_place_index<1>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, const int, long> v(std::in_place_index<1>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<0>, x);
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<1>, x);
+ assert(v.index() == 1);
+ assert(std::get<1>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<2>, x);
+ assert(v.index() == 2);
+ assert(std::get<2>(v) == x);
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
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
new file mode 100644
index 000000000000..608cdf9d6efb
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class Up, class ...Args>
+// constexpr explicit
+// variant(in_place_index_t<I>, initializer_list<Up>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+void test_ctor_sfinae() {
+ using IL = std::initializer_list<int>;
+ { // just init list
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(std::is_constructible<V, std::in_place_index_t<0>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, IL>(), "");
+ }
+ { // too many arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<0>, IL, int>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, IL, int>(),
+ "");
+ }
+ { // too few arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<1>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, IL>(), "");
+ }
+ { // init list and arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<1>, IL, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, IL, int>(),
+ "");
+ }
+ { // not constructible from arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<2>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<2>, IL>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<InitList, InitListArg, InitList> v(
+ std::in_place_index<0>, {1, 2, 3});
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg, InitList> v(
+ std::in_place_index<2>, {1, 2, 3});
+ static_assert(v.index() == 2, "");
+ static_assert(std::get<2>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg, InitListArg> v(
+ std::in_place_index<1>, {1, 2, 3, 4}, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v).size == 4, "");
+ static_assert(std::get<1>(v).value == 42, "");
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
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
new file mode 100644
index 000000000000..a023f02bad6e
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class Tp, class ...Args>
+// constexpr explicit variant(in_place_type_t<Tp>, Args&&...);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+void test_ctor_sfinae() {
+ {
+ using V = std::variant<int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<int>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, long long>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<long>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<long>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<int *>, int *>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int *>, int *>(),
+ "");
+ }
+ { // duplicate type
+ using V = std::variant<int, long, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int>(), "");
+ }
+ { // args not convertible to type
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int *>(), "");
+ }
+ { // type not in variant
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<long long>, int>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<long long>, int>(),
+ "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<int> v(std::in_place_type<int>, 42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long> v(std::in_place_type<long>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, const int, long> v(
+ std::in_place_type<const int>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<const int>, x);
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<volatile int>, x);
+ assert(v.index() == 1);
+ assert(std::get<1>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<int>, x);
+ assert(v.index() == 2);
+ assert(std::get<2>(v) == x);
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
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
new file mode 100644
index 000000000000..e151572c4666
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
@@ -0,0 +1,110 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class Tp, class Up, class ...Args>
+// constexpr explicit
+// variant(in_place_type_t<Tp>, initializer_list<Up>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+void test_ctor_sfinae() {
+ using IL = std::initializer_list<int>;
+ { // just init list
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<InitList>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<InitList>, IL>(),
+ "");
+ }
+ { // too many arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(!std::is_constructible<V, std::in_place_type_t<InitList>, IL,
+ int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitList>, IL, int>(), "");
+ }
+ { // too few arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<InitListArg>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<InitListArg>, IL>(),
+ "");
+ }
+ { // init list and arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(std::is_constructible<V, std::in_place_type_t<InitListArg>,
+ IL, int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitListArg>, IL, int>(), "");
+ }
+ { // not constructible from arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, IL>(), "");
+ }
+ { // duplicate types in variant
+ using V = std::variant<InitListArg, InitListArg, int>;
+ static_assert(!std::is_constructible<V, std::in_place_type_t<InitListArg>,
+ IL, int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitListArg>, IL, int>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<InitList, InitListArg> v(
+ std::in_place_type<InitList>, {1, 2, 3});
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg> v(
+ std::in_place_type<InitListArg>, {1, 2, 3, 4}, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v).size == 4, "");
+ static_assert(std::get<1>(v).value == 42, "");
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
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
new file mode 100644
index 000000000000..66f67fe8d3f2
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant(variant&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct ThrowsMove {
+ ThrowsMove(ThrowsMove &&) noexcept(false) {}
+};
+
+struct NoCopy {
+ NoCopy(const NoCopy &) = delete;
+};
+
+struct MoveOnly {
+ int value;
+ MoveOnly(int v) : value(v) {}
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+};
+
+struct MoveOnlyNT {
+ int value;
+ MoveOnlyNT(int v) : value(v) {}
+ MoveOnlyNT(const MoveOnlyNT &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&other) : value(other.value) { other.value = -1; }
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct MakeEmptyT {
+ static int alive;
+ MakeEmptyT() { ++alive; }
+ MakeEmptyT(const MakeEmptyT &) {
+ ++alive;
+ // Don't throw from the copy constructor since variant's assignment
+ // operator performs a copy before committing to the assignment.
+ }
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+ ~MakeEmptyT() { --alive; }
+};
+
+int MakeEmptyT::alive = 0;
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = v2;
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_move_noexcept() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(!std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, ThrowsMove>;
+ static_assert(!std::is_nothrow_move_constructible<V>::value, "");
+ }
+}
+
+void test_move_ctor_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_move_constructible<V>::value, "");
+ }
+}
+
+void test_move_ctor_basic() {
+ {
+ std::variant<int> v(std::in_place_index<0>, 42);
+ std::variant<int> v2 = std::move(v);
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2) == 42);
+ }
+ {
+ std::variant<int, long> v(std::in_place_index<1>, 42);
+ std::variant<int, long> v2 = std::move(v);
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2) == 42);
+ }
+ {
+ std::variant<MoveOnly> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<MoveOnly> v2(std::move(v));
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, MoveOnly> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, MoveOnly> v2(std::move(v));
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2).value == 42);
+ }
+ {
+ std::variant<MoveOnlyNT> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<MoveOnlyNT> v2(std::move(v));
+ assert(v2.index() == 0);
+ assert(std::get<0>(v).value == -1);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, MoveOnlyNT> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, MoveOnlyNT> v2(std::move(v));
+ assert(v2.index() == 1);
+ assert(std::get<1>(v).value == -1);
+ assert(std::get<1>(v2).value == 42);
+ }
+}
+
+void test_move_ctor_valueless_by_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v(std::move(v1));
+ assert(v.valueless_by_exception());
+#endif
+}
+
+template <size_t Idx>
+constexpr bool test_constexpr_ctor_extension_imp(
+ std::variant<long, void*, const int> const& v)
+{
+ auto copy = v;
+ auto v2 = std::move(copy);
+ return v2.index() == v.index() &&
+ v2.index() == Idx &&
+ std::get<Idx>(v2) == std::get<Idx>(v);
+}
+
+void test_constexpr_move_ctor_extension() {
+#ifdef _LIBCPP_VERSION
+ using V = std::variant<long, void*, const int>;
+ static_assert(std::is_trivially_copyable<V>::value, "");
+ 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)), "");
+#endif
+}
+
+int main() {
+ test_move_ctor_basic();
+ test_move_ctor_valueless_by_exception();
+ test_move_noexcept();
+ test_move_ctor_sfinae();
+ test_constexpr_move_ctor_extension();
+}
diff --git a/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp b/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp
new file mode 100644
index 000000000000..7299394ee7bb
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// ~variant();
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct NonTDtor {
+ static int count;
+ NonTDtor() = default;
+ ~NonTDtor() { ++count; }
+};
+int NonTDtor::count = 0;
+static_assert(!std::is_trivially_destructible<NonTDtor>::value, "");
+
+struct NonTDtor1 {
+ static int count;
+ NonTDtor1() = default;
+ ~NonTDtor1() { ++count; }
+};
+int NonTDtor1::count = 0;
+static_assert(!std::is_trivially_destructible<NonTDtor1>::value, "");
+
+struct TDtor {
+ TDtor(const TDtor &) {} // non-trivial copy
+ ~TDtor() = default;
+};
+static_assert(!std::is_trivially_copy_constructible<TDtor>::value, "");
+static_assert(std::is_trivially_destructible<TDtor>::value, "");
+
+int main() {
+ {
+ using V = std::variant<int, long, TDtor>;
+ static_assert(std::is_trivially_destructible<V>::value, "");
+ }
+ {
+ using V = std::variant<NonTDtor, int, NonTDtor1>;
+ static_assert(!std::is_trivially_destructible<V>::value, "");
+ {
+ V v(std::in_place_index<0>);
+ assert(NonTDtor::count == 0);
+ assert(NonTDtor1::count == 0);
+ }
+ assert(NonTDtor::count == 1);
+ assert(NonTDtor1::count == 0);
+ NonTDtor::count = 0;
+ { V v(std::in_place_index<1>); }
+ assert(NonTDtor::count == 0);
+ assert(NonTDtor1::count == 0);
+ {
+ V v(std::in_place_index<2>);
+ assert(NonTDtor::count == 0);
+ assert(NonTDtor1::count == 0);
+ }
+ assert(NonTDtor::count == 0);
+ assert(NonTDtor1::count == 1);
+ }
+}
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
new file mode 100644
index 000000000000..8f694cfd5eda
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class ...Args> void emplace(Args&&... args);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+template <class Var, size_t I, class... Args>
+constexpr auto test_emplace_exists_imp(int) -> decltype(
+ std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
+ return true;
+}
+
+template <class, size_t, class...>
+constexpr auto test_emplace_exists_imp(long) -> bool {
+ return false;
+}
+
+template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
+ return test_emplace_exists_imp<Var, I, Args...>(0);
+}
+
+void test_emplace_sfinae() {
+ {
+ using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
+ static_assert(emplace_exists<V, 0>(), "");
+ static_assert(emplace_exists<V, 0, int>(), "");
+ static_assert(!emplace_exists<V, 0, decltype(nullptr)>(),
+ "cannot construct");
+ static_assert(emplace_exists<V, 1, decltype(nullptr)>(), "");
+ static_assert(emplace_exists<V, 1, int *>(), "");
+ static_assert(!emplace_exists<V, 1, const int *>(), "");
+ static_assert(!emplace_exists<V, 1, int>(), "cannot construct");
+ static_assert(emplace_exists<V, 2, const int *>(), "");
+ static_assert(emplace_exists<V, 2, int *>(), "");
+ static_assert(!emplace_exists<V, 3>(), "cannot construct");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
+ static_assert(emplace_exists<V, 0>(), "");
+ static_assert(emplace_exists<V, 0, int>(), "");
+ static_assert(emplace_exists<V, 0, long long>(), "");
+ static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
+ static_assert(emplace_exists<V, 1, int &>(), "");
+ static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
+ static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
+ static_assert(emplace_exists<V, 2, int &>(), "");
+ static_assert(emplace_exists<V, 2, const int &>(), "");
+ static_assert(emplace_exists<V, 2, int &&>(), "");
+ static_assert(!emplace_exists<V, 2, void *>(),
+ "not constructible from void*");
+ static_assert(emplace_exists<V, 3, int>(), "");
+ static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, 4>(), "no ctors");
+ }
+#endif
+}
+
+void test_basic() {
+ {
+ using V = std::variant<int>;
+ V v(42);
+ v.emplace<0>();
+ assert(std::get<0>(v) == 0);
+ v.emplace<0>(42);
+ assert(std::get<0>(v) == 42);
+ }
+ {
+ using V =
+ std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
+ const int x = 100;
+ V v(std::in_place_index<0>, -1);
+ // default emplace a value
+ v.emplace<1>();
+ assert(std::get<1>(v) == 0);
+ v.emplace<2>(&x);
+ assert(std::get<2>(v) == &x);
+ // emplace with multiple args
+ v.emplace<4>(3, 'a');
+ assert(std::get<4>(v) == "aaa");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
+ std::string>;
+ const int x = 100;
+ int y = 42;
+ int z = 43;
+ V v(std::in_place_index<0>, -1);
+ // default emplace a value
+ v.emplace<1>();
+ assert(std::get<1>(v) == 0);
+ // emplace a reference
+ v.emplace<2>(x);
+ assert(&std::get<2>(v) == &x);
+ // emplace an rvalue reference
+ v.emplace<3>(std::move(y));
+ assert(&std::get<3>(v) == &y);
+ // re-emplace a new reference over the active member
+ v.emplace<3>(std::move(z));
+ assert(&std::get<3>(v) == &z);
+ // emplace with multiple args
+ v.emplace<5>(3, 'a');
+ assert(std::get<5>(v) == "aaa");
+ }
+#endif
+}
+
+int main() {
+ test_basic();
+ test_emplace_sfinae();
+}
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
new file mode 100644
index 000000000000..f466b160cb4f
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
@@ -0,0 +1,85 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class U, class ...Args>
+// void emplace(initializer_list<U> il,Args&&... args);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+template <class Var, size_t I, class... Args>
+constexpr auto test_emplace_exists_imp(int) -> decltype(
+ std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
+ return true;
+}
+
+template <class, size_t, class...>
+constexpr auto test_emplace_exists_imp(long) -> bool {
+ return false;
+}
+
+template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
+ return test_emplace_exists_imp<Var, I, Args...>(0);
+}
+
+void test_emplace_sfinae() {
+ using V =
+ std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>;
+ using IL = std::initializer_list<int>;
+ static_assert(!emplace_exists<V, 1, IL>(), "no such constructor");
+ static_assert(emplace_exists<V, 2, IL>(), "");
+ static_assert(!emplace_exists<V, 2, int>(), "args don't match");
+ static_assert(!emplace_exists<V, 2, IL, int>(), "too many args");
+ static_assert(emplace_exists<V, 3, IL, int>(), "");
+ static_assert(!emplace_exists<V, 3, int>(), "args don't match");
+ static_assert(!emplace_exists<V, 3, IL>(), "too few args");
+ static_assert(!emplace_exists<V, 3, IL, int, int>(), "too many args");
+}
+
+void test_basic() {
+ using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>;
+ V v;
+ v.emplace<1>({1, 2, 3});
+ assert(std::get<1>(v).size == 3);
+ v.emplace<2>({1, 2, 3, 4}, 42);
+ assert(std::get<2>(v).size == 4);
+ assert(std::get<2>(v).value == 42);
+ v.emplace<1>({1});
+ assert(std::get<1>(v).size == 1);
+}
+
+int main() {
+ test_basic();
+ test_emplace_sfinae();
+}
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
new file mode 100644
index 000000000000..4ca2cc4803e3
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
@@ -0,0 +1,138 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class T, class ...Args> void emplace(Args&&... args);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+template <class Var, class T, class... Args>
+constexpr auto test_emplace_exists_imp(int) -> decltype(
+ std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
+ return true;
+}
+
+template <class, class, class...>
+constexpr auto test_emplace_exists_imp(long) -> bool {
+ return false;
+}
+
+template <class... Args> constexpr bool emplace_exists() {
+ return test_emplace_exists_imp<Args...>(0);
+}
+
+void test_emplace_sfinae() {
+ {
+ using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
+ static_assert(emplace_exists<V, int>(), "");
+ static_assert(emplace_exists<V, int, int>(), "");
+ static_assert(!emplace_exists<V, int, decltype(nullptr)>(),
+ "cannot construct");
+ static_assert(emplace_exists<V, void *, decltype(nullptr)>(), "");
+ static_assert(!emplace_exists<V, void *, int>(), "cannot construct");
+ static_assert(emplace_exists<V, void *, int *>(), "");
+ static_assert(!emplace_exists<V, void *, const int *>(), "");
+ static_assert(emplace_exists<V, const void *, const int *>(), "");
+ static_assert(emplace_exists<V, const void *, int *>(), "");
+ static_assert(!emplace_exists<V, TestTypes::NoCtors>(), "cannot construct");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ using V = std::variant<int, int &, const int &, int &&, long, long,
+ TestTypes::NoCtors>;
+ static_assert(emplace_exists<V, int>(), "");
+ static_assert(emplace_exists<V, int, int>(), "");
+ static_assert(emplace_exists<V, int, long long>(), "");
+ static_assert(!emplace_exists<V, int, int, int>(), "too many args");
+ static_assert(emplace_exists<V, int &, int &>(), "");
+ static_assert(!emplace_exists<V, int &>(), "cannot default construct ref");
+ static_assert(!emplace_exists<V, int &, const int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, int &, int &&>(), "cannot bind ref");
+ static_assert(emplace_exists<V, const int &, int &>(), "");
+ static_assert(emplace_exists<V, const int &, const int &>(), "");
+ static_assert(emplace_exists<V, const int &, int &&>(), "");
+ static_assert(!emplace_exists<V, const int &, void *>(),
+ "not constructible from void*");
+ static_assert(emplace_exists<V, int &&, int>(), "");
+ static_assert(!emplace_exists<V, int &&, int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, int &&, const int &>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, int &&, const int &&>(), "cannot bind ref");
+ static_assert(!emplace_exists<V, long, long>(), "ambiguous");
+ static_assert(!emplace_exists<V, TestTypes::NoCtors>(),
+ "cannot construct void");
+#endif
+}
+
+void test_basic() {
+ {
+ using V = std::variant<int>;
+ V v(42);
+ v.emplace<int>();
+ assert(std::get<0>(v) == 0);
+ v.emplace<int>(42);
+ assert(std::get<0>(v) == 42);
+ }
+ {
+ using V =
+ std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
+ const int x = 100;
+ V v(std::in_place_type<int>, -1);
+ // default emplace a value
+ v.emplace<long>();
+ assert(std::get<1>(v) == 0);
+ v.emplace<const void *>(&x);
+ assert(std::get<2>(v) == &x);
+ // emplace with multiple args
+ v.emplace<std::string>(3, 'a');
+ assert(std::get<4>(v) == "aaa");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
+ std::string>;
+ const int x = 100;
+ int y = 42;
+ int z = 43;
+ V v(std::in_place_index<0>, -1);
+ // default emplace a value
+ v.emplace<long>();
+ assert(std::get<long>(v) == 0);
+ // emplace a reference
+ v.emplace<const int &>(x);
+ assert(&std::get<const int &>(v) == &x);
+ // emplace an rvalue reference
+ v.emplace<int &&>(std::move(y));
+ assert(&std::get<int &&>(v) == &y);
+ // re-emplace a new reference over the active member
+ v.emplace<int &&>(std::move(z));
+ assert(&std::get<int &&>(v) == &z);
+ // emplace with multiple args
+ v.emplace<std::string>(3, 'a');
+ assert(std::get<std::string>(v) == "aaa");
+ }
+#endif
+}
+
+int main() {
+ test_basic();
+ test_emplace_sfinae();
+}
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
new file mode 100644
index 000000000000..b2be8ac5b3fd
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
@@ -0,0 +1,85 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class T, class U, class ...Args>
+// void emplace(initializer_list<U> il,Args&&... args);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+template <class Var, class T, class... Args>
+constexpr auto test_emplace_exists_imp(int) -> decltype(
+ std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
+ return true;
+}
+
+template <class, class, class...>
+constexpr auto test_emplace_exists_imp(long) -> bool {
+ return false;
+}
+
+template <class... Args> constexpr bool emplace_exists() {
+ return test_emplace_exists_imp<Args...>(0);
+}
+
+void test_emplace_sfinae() {
+ using V =
+ std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>;
+ using IL = std::initializer_list<int>;
+ static_assert(emplace_exists<V, InitList, IL>(), "");
+ static_assert(!emplace_exists<V, InitList, int>(), "args don't match");
+ static_assert(!emplace_exists<V, InitList, IL, int>(), "too many args");
+ static_assert(emplace_exists<V, InitListArg, IL, int>(), "");
+ static_assert(!emplace_exists<V, InitListArg, int>(), "args don't match");
+ static_assert(!emplace_exists<V, InitListArg, IL>(), "too few args");
+ static_assert(!emplace_exists<V, InitListArg, IL, int, int>(),
+ "too many args");
+}
+
+void test_basic() {
+ using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>;
+ V v;
+ v.emplace<InitList>({1, 2, 3});
+ assert(std::get<InitList>(v).size == 3);
+ v.emplace<InitListArg>({1, 2, 3, 4}, 42);
+ assert(std::get<InitListArg>(v).size == 4);
+ assert(std::get<InitListArg>(v).value == 42);
+ v.emplace<InitList>({1});
+ assert(std::get<InitList>(v).size == 1);
+}
+
+int main() {
+ test_basic();
+ test_emplace_sfinae();
+}
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
new file mode 100644
index 000000000000..4b30188ce6ff
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// Clang 3.8 doesn't allow constexpr variables of non-literal type
+// XFAIL: clang-3.8, apple-clang-7, apple-clang-8
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// constexpr size_t index() const noexcept;
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+int main() {
+ {
+ using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ constexpr V v;
+ static_assert(v.index() == 0, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v(std::in_place_index<1>);
+ static_assert(v.index() == 1, "");
+ }
+ {
+ using V = std::variant<int, std::string>;
+ V v("abc");
+ assert(v.index() == 1);
+ v = 42;
+ assert(v.index() == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v;
+ assert(v.index() == 0);
+ makeEmpty(v);
+ assert(v.index() == std::variant_npos);
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..8546beb1319c
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// Clang 3.8 doesn't allow constexpr variables of non-literal type
+// XFAIL: clang-3.8, apple-clang-7, apple-clang-8
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// constexpr bool valueless_by_exception() const noexcept;
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "archetypes.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+int main() {
+ {
+ using V = std::variant<int, ConstexprTestTypes::NoCtors>;
+ constexpr V v;
+ static_assert(!v.valueless_by_exception(), "");
+ }
+ {
+ using V = std::variant<int, long, std::string>;
+ const V v("abc");
+ assert(!v.valueless_by_exception());
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v;
+ assert(!v.valueless_by_exception());
+ makeEmpty(v);
+ assert(v.valueless_by_exception());
+ }
+#endif
+}
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
new file mode 100644
index 000000000000..416c6b4e334d
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -0,0 +1,591 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// void swap(variant& rhs) noexcept(see below)
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct NotSwappable {};
+void swap(NotSwappable &, NotSwappable &) = delete;
+
+struct NotCopyable {
+ NotCopyable() = default;
+ NotCopyable(const NotCopyable &) = delete;
+ NotCopyable &operator=(const NotCopyable &) = delete;
+};
+
+struct NotCopyableWithSwap {
+ NotCopyableWithSwap() = default;
+ NotCopyableWithSwap(const NotCopyableWithSwap &) = delete;
+ NotCopyableWithSwap &operator=(const NotCopyableWithSwap &) = delete;
+};
+void swap(NotCopyableWithSwap &, NotCopyableWithSwap) {}
+
+struct NotMoveAssignable {
+ NotMoveAssignable() = default;
+ NotMoveAssignable(NotMoveAssignable &&) = default;
+ NotMoveAssignable &operator=(NotMoveAssignable &&) = delete;
+};
+
+struct NotMoveAssignableWithSwap {
+ NotMoveAssignableWithSwap() = default;
+ NotMoveAssignableWithSwap(NotMoveAssignableWithSwap &&) = default;
+ NotMoveAssignableWithSwap &operator=(NotMoveAssignableWithSwap &&) = delete;
+};
+void swap(NotMoveAssignableWithSwap &, NotMoveAssignableWithSwap &) noexcept {}
+
+template <bool Throws> void do_throw() {}
+
+template <> void do_throw<true>() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ throw 42;
+#else
+ std::abort();
+#endif
+}
+
+template <bool NT_Copy, bool NT_Move, bool NT_CopyAssign, bool NT_MoveAssign,
+ bool NT_Swap, bool EnableSwap = true>
+struct NothrowTypeImp {
+ static int move_called;
+ static int move_assign_called;
+ static int swap_called;
+ static void reset() { move_called = move_assign_called = swap_called = 0; }
+ NothrowTypeImp() = default;
+ explicit NothrowTypeImp(int v) : value(v) {}
+ NothrowTypeImp(const NothrowTypeImp &o) noexcept(NT_Copy) : value(o.value) {
+ assert(false);
+ } // never called by test
+ NothrowTypeImp(NothrowTypeImp &&o) noexcept(NT_Move) : value(o.value) {
+ ++move_called;
+ do_throw<!NT_Move>();
+ o.value = -1;
+ }
+ NothrowTypeImp &operator=(const NothrowTypeImp &) noexcept(NT_CopyAssign) {
+ assert(false);
+ return *this;
+ } // never called by the tests
+ NothrowTypeImp &operator=(NothrowTypeImp &&o) noexcept(NT_MoveAssign) {
+ ++move_assign_called;
+ do_throw<!NT_MoveAssign>();
+ value = o.value;
+ o.value = -1;
+ return *this;
+ }
+ int value;
+};
+template <bool NT_Copy, bool NT_Move, bool NT_CopyAssign, bool NT_MoveAssign,
+ bool NT_Swap, bool EnableSwap>
+int NothrowTypeImp<NT_Copy, NT_Move, NT_CopyAssign, NT_MoveAssign, NT_Swap,
+ EnableSwap>::move_called = 0;
+template <bool NT_Copy, bool NT_Move, bool NT_CopyAssign, bool NT_MoveAssign,
+ bool NT_Swap, bool EnableSwap>
+int NothrowTypeImp<NT_Copy, NT_Move, NT_CopyAssign, NT_MoveAssign, NT_Swap,
+ EnableSwap>::move_assign_called = 0;
+template <bool NT_Copy, bool NT_Move, bool NT_CopyAssign, bool NT_MoveAssign,
+ bool NT_Swap, bool EnableSwap>
+int NothrowTypeImp<NT_Copy, NT_Move, NT_CopyAssign, NT_MoveAssign, NT_Swap,
+ EnableSwap>::swap_called = 0;
+
+template <bool NT_Copy, bool NT_Move, bool NT_CopyAssign, bool NT_MoveAssign,
+ bool NT_Swap>
+void swap(NothrowTypeImp<NT_Copy, NT_Move, NT_CopyAssign, NT_MoveAssign,
+ NT_Swap, true> &lhs,
+ NothrowTypeImp<NT_Copy, NT_Move, NT_CopyAssign, NT_MoveAssign,
+ NT_Swap, true> &rhs) noexcept(NT_Swap) {
+ lhs.swap_called++;
+ do_throw<!NT_Swap>();
+ int tmp = lhs.value;
+ lhs.value = rhs.value;
+ rhs.value = tmp;
+}
+
+// throwing copy, nothrow move ctor/assign, no swap provided
+using NothrowMoveable = NothrowTypeImp<false, true, false, true, false, false>;
+// throwing copy and move assign, nothrow move ctor, no swap provided
+using NothrowMoveCtor = NothrowTypeImp<false, true, false, false, false, false>;
+// nothrow move ctor, throwing move assignment, swap provided
+using NothrowMoveCtorWithThrowingSwap =
+ NothrowTypeImp<false, true, false, false, false, true>;
+// throwing move ctor, nothrow move assignment, no swap provided
+using ThrowingMoveCtor =
+ NothrowTypeImp<false, false, false, true, false, false>;
+// throwing special members, nothrowing swap
+using ThrowingTypeWithNothrowSwap =
+ NothrowTypeImp<false, false, false, false, true, true>;
+using NothrowTypeWithThrowingSwap =
+ NothrowTypeImp<true, true, true, true, false, true>;
+// throwing move assign with nothrow move and nothrow swap
+using ThrowingMoveAssignNothrowMoveCtorWithSwap =
+ NothrowTypeImp<false, true, false, false, true, true>;
+// throwing move assign with nothrow move but no swap.
+using ThrowingMoveAssignNothrowMoveCtor =
+ NothrowTypeImp<false, true, false, false, false, false>;
+
+struct NonThrowingNonNoexceptType {
+ static int move_called;
+ static void reset() { move_called = 0; }
+ NonThrowingNonNoexceptType() = default;
+ NonThrowingNonNoexceptType(int v) : value(v) {}
+ NonThrowingNonNoexceptType(NonThrowingNonNoexceptType &&o) noexcept(false)
+ : value(o.value) {
+ ++move_called;
+ o.value = -1;
+ }
+ NonThrowingNonNoexceptType &
+ operator=(NonThrowingNonNoexceptType &&) noexcept(false) {
+ assert(false); // never called by the tests.
+ return *this;
+ }
+ int value;
+};
+int NonThrowingNonNoexceptType::move_called = 0;
+
+struct ThrowsOnSecondMove {
+ int value;
+ int move_count;
+ ThrowsOnSecondMove(int v) : value(v), move_count(0) {}
+ ThrowsOnSecondMove(ThrowsOnSecondMove &&o) noexcept(false)
+ : value(o.value), move_count(o.move_count + 1) {
+ if (move_count == 2)
+ do_throw<true>();
+ o.value = -1;
+ }
+ ThrowsOnSecondMove &operator=(ThrowsOnSecondMove &&) {
+ assert(false); // not called by test
+ return *this;
+ }
+};
+
+void test_swap_valueless_by_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, MakeEmptyT>;
+ { // both empty
+ V v1;
+ makeEmpty(v1);
+ V v2;
+ makeEmpty(v2);
+ assert(MakeEmptyT::alive == 0);
+ { // member swap
+ v1.swap(v2);
+ assert(v1.valueless_by_exception());
+ assert(v2.valueless_by_exception());
+ assert(MakeEmptyT::alive == 0);
+ }
+ { // non-member swap
+ swap(v1, v2);
+ assert(v1.valueless_by_exception());
+ assert(v2.valueless_by_exception());
+ assert(MakeEmptyT::alive == 0);
+ }
+ }
+ { // only one empty
+ V v1(42);
+ V v2;
+ makeEmpty(v2);
+ { // member swap
+ v1.swap(v2);
+ assert(v1.valueless_by_exception());
+ assert(std::get<0>(v2) == 42);
+ // swap again
+ v2.swap(v1);
+ assert(v2.valueless_by_exception());
+ assert(std::get<0>(v1) == 42);
+ }
+ { // non-member swap
+ swap(v1, v2);
+ assert(v1.valueless_by_exception());
+ assert(std::get<0>(v2) == 42);
+ // swap again
+ swap(v1, v2);
+ assert(v2.valueless_by_exception());
+ assert(std::get<0>(v1) == 42);
+ }
+ }
+#endif
+}
+
+void test_swap_same_alternative() {
+ {
+ using T = ThrowingTypeWithNothrowSwap;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>, 100);
+ v1.swap(v2);
+ assert(T::swap_called == 1);
+ assert(std::get<0>(v1).value == 100);
+ assert(std::get<0>(v2).value == 42);
+ swap(v1, v2);
+ assert(T::swap_called == 2);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<0>(v2).value == 100);
+ }
+ {
+ using T = NothrowMoveable;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>, 100);
+ v1.swap(v2);
+ assert(T::swap_called == 0);
+ assert(T::move_called == 1);
+ assert(T::move_assign_called == 2);
+ assert(std::get<0>(v1).value == 100);
+ assert(std::get<0>(v2).value == 42);
+ T::reset();
+ swap(v1, v2);
+ assert(T::swap_called == 0);
+ assert(T::move_called == 1);
+ assert(T::move_assign_called == 2);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<0>(v2).value == 100);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using T = NothrowTypeWithThrowingSwap;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T::swap_called == 1);
+ assert(T::move_called == 0);
+ assert(T::move_assign_called == 0);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<0>(v2).value == 100);
+ }
+ {
+ using T = ThrowingMoveCtor;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T::move_called == 1); // call threw
+ assert(T::move_assign_called == 0);
+ assert(std::get<0>(v1).value ==
+ 42); // throw happened before v1 was moved from
+ assert(std::get<0>(v2).value == 100);
+ }
+ {
+ using T = ThrowingMoveAssignNothrowMoveCtor;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<0>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T::move_called == 1);
+ assert(T::move_assign_called == 1); // call threw and didn't complete
+ assert(std::get<0>(v1).value == -1); // v1 was moved from
+ assert(std::get<0>(v2).value == 100);
+ }
+#endif
+}
+
+void test_swap_different_alternatives() {
+ {
+ using T = NothrowMoveCtorWithThrowingSwap;
+ using V = std::variant<T, int>;
+ T::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ v1.swap(v2);
+ assert(T::swap_called == 0);
+ // The libc++ implementation double copies the argument, and not
+ // the variant swap is called on.
+ LIBCPP_ASSERT(T::move_called == 1);
+ assert(T::move_called <= 2);
+ assert(T::move_assign_called == 0);
+ assert(std::get<1>(v1) == 100);
+ assert(std::get<0>(v2).value == 42);
+ T::reset();
+ swap(v1, v2);
+ assert(T::swap_called == 0);
+ LIBCPP_ASSERT(T::move_called == 2);
+ assert(T::move_called <= 2);
+ assert(T::move_assign_called == 0);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<1>(v2) == 100);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using T1 = ThrowingTypeWithNothrowSwap;
+ using T2 = NonThrowingNonNoexceptType;
+ using V = std::variant<T1, T2>;
+ T1::reset();
+ T2::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T1::swap_called == 0);
+ assert(T1::move_called == 1); // throws
+ assert(T1::move_assign_called == 0);
+ // FIXME: libc++ shouldn't move from T2 here.
+ LIBCPP_ASSERT(T2::move_called == 1);
+ assert(T2::move_called <= 1);
+ assert(std::get<0>(v1).value == 42);
+ if (T2::move_called != 0)
+ assert(v2.valueless_by_exception());
+ else
+ assert(std::get<1>(v2).value == 100);
+ }
+ {
+ using T1 = NonThrowingNonNoexceptType;
+ using T2 = ThrowingTypeWithNothrowSwap;
+ using V = std::variant<T1, T2>;
+ T1::reset();
+ T2::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ LIBCPP_ASSERT(T1::move_called == 0);
+ assert(T1::move_called <= 1);
+ assert(T2::swap_called == 0);
+ assert(T2::move_called == 1); // throws
+ assert(T2::move_assign_called == 0);
+ if (T1::move_called != 0)
+ assert(v1.valueless_by_exception());
+ else
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<1>(v2).value == 100);
+ }
+// FIXME: The tests below are just very libc++ specific
+#ifdef _LIBCPP_VERSION
+ {
+ using T1 = ThrowsOnSecondMove;
+ using T2 = NonThrowingNonNoexceptType;
+ using V = std::variant<T1, T2>;
+ T2::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ v1.swap(v2);
+ assert(T2::move_called == 2);
+ assert(std::get<1>(v1).value == 100);
+ assert(std::get<0>(v2).value == 42);
+ assert(std::get<0>(v2).move_count == 1);
+ }
+ {
+ using T1 = NonThrowingNonNoexceptType;
+ using T2 = ThrowsOnSecondMove;
+ using V = std::variant<T1, T2>;
+ T1::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T1::move_called == 1);
+ assert(v1.valueless_by_exception());
+ assert(std::get<0>(v2).value == 42);
+ }
+#endif
+// testing libc++ extension. If either variant stores a nothrow move
+// constructible type v1.swap(v2) provides the strong exception safety
+// guarantee.
+#ifdef _LIBCPP_VERSION
+ {
+
+ using T1 = ThrowingTypeWithNothrowSwap;
+ using T2 = NothrowMoveable;
+ using V = std::variant<T1, T2>;
+ T1::reset();
+ T2::reset();
+ V v1(std::in_place_index<0>, 42);
+ V v2(std::in_place_index<1>, 100);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T1::swap_called == 0);
+ assert(T1::move_called == 1);
+ assert(T1::move_assign_called == 0);
+ assert(T2::swap_called == 0);
+ assert(T2::move_called == 2);
+ assert(T2::move_assign_called == 0);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<1>(v2).value == 100);
+ // swap again, but call v2's swap.
+ T1::reset();
+ T2::reset();
+ try {
+ v2.swap(v1);
+ assert(false);
+ } catch (int) {
+ }
+ assert(T1::swap_called == 0);
+ assert(T1::move_called == 1);
+ assert(T1::move_assign_called == 0);
+ assert(T2::swap_called == 0);
+ assert(T2::move_called == 2);
+ assert(T2::move_assign_called == 0);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<1>(v2).value == 100);
+ }
+#endif // _LIBCPP_VERSION
+#endif
+}
+
+template <class Var>
+constexpr auto has_swap_member_imp(int)
+ -> decltype(std::declval<Var &>().swap(std::declval<Var &>()), true) {
+ return true;
+}
+
+template <class Var> constexpr auto has_swap_member_imp(long) -> bool {
+ return false;
+}
+
+template <class Var> constexpr bool has_swap_member() {
+ return has_swap_member_imp<Var>(0);
+}
+
+void test_swap_sfinae() {
+ {
+ // This variant type does not provide either a member or non-member swap
+ // but is still swappable via the generic swap algorithm, since the
+ // variant is move constructible and move assignable.
+ using V = std::variant<int, NotSwappable>;
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>());
+ static_assert(std::is_swappable_v<V>, "");
+ }
+ {
+ using V = std::variant<int, NotCopyable>;
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), "");
+ static_assert(!std::is_swappable_v<V>, "");
+ }
+ {
+ using V = std::variant<int, NotCopyableWithSwap>;
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), "");
+ static_assert(!std::is_swappable_v<V>, "");
+ }
+ {
+ using V = std::variant<int, NotMoveAssignable>;
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), "");
+ static_assert(!std::is_swappable_v<V>, "");
+ }
+}
+
+void test_swap_noexcept() {
+ {
+ using V = std::variant<int, NothrowMoveable>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ using V = std::variant<int, NothrowMoveCtor>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(!std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ using V = std::variant<int, ThrowingTypeWithNothrowSwap>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(!std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ using V = std::variant<int, ThrowingMoveAssignNothrowMoveCtor>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(!std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ using V = std::variant<int, ThrowingMoveAssignNothrowMoveCtorWithSwap>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ using V = std::variant<int, NotMoveAssignableWithSwap>;
+ static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
+ static_assert(std::is_nothrow_swappable_v<V>, "");
+ // instantiate swap
+ V v1, v2;
+ v1.swap(v2);
+ swap(v1, v2);
+ }
+ {
+ // This variant type does not provide either a member or non-member swap
+ // but is still swappable via the generic swap algorithm, since the
+ // variant is move constructible and move assignable.
+ using V = std::variant<int, NotSwappable>;
+ LIBCPP_STATIC_ASSERT(!has_swap_member<V>());
+ static_assert(std::is_swappable_v<V>, "");
+ static_assert(std::is_nothrow_swappable_v<V>, "");
+ V v1, v2;
+ swap(v1, v2);
+ }
+}
+
+#ifdef _LIBCPP_VERSION
+// This is why variant should SFINAE member swap. :-)
+template class std::variant<int, NotSwappable>;
+#endif
+
+int main() {
+ test_swap_valueless_by_exception();
+ test_swap_same_alternative();
+ test_swap_different_alternatives();
+ test_swap_sfinae();
+ test_swap_noexcept();
+}
diff --git a/test/std/utilities/variant/variant.variant/variant_array.fail.cpp b/test/std/utilities/variant/variant.variant/variant_array.fail.cpp
new file mode 100644
index 000000000000..11ee332e216e
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant_array.fail.cpp
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+
+#include <variant>
+#include <type_traits>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include "test_convertible.hpp"
+
+int main()
+{
+ // expected-error@variant:* 3 {{static_assert failed}}
+ std::variant<int, int[]> v; // expected-note {{requested here}}
+ std::variant<int, int[42]> v2; // expected-note {{requested here}}
+ std::variant<int, int[][42]> v3; // expected-note {{requested here}}
+}
diff --git a/test/std/utilities/variant/variant.variant/variant_empty.fail.cpp b/test/std/utilities/variant/variant.variant/variant_empty.fail.cpp
new file mode 100644
index 000000000000..2d8cc0b3da0f
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant_empty.fail.cpp
@@ -0,0 +1,26 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+int main()
+{
+ // expected-error@variant:* 1 {{static_assert failed}}
+ std::variant<> v; // expected-note {{requested here}}
+}
diff --git a/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp b/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp
new file mode 100644
index 000000000000..bda27f0e5eba
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp
@@ -0,0 +1,28 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+int main()
+{
+ // expected-error@variant:* 3 {{static_assert failed}}
+ std::variant<int, int&> v; // expected-note {{requested here}}
+ std::variant<int, const int &> v2; // expected-note {{requested here}}
+ std::variant<int, int&&> v3; // expected-note {{requested here}}
+}
diff --git a/test/std/utilities/variant/variant.variant/variant_void.fail.cpp b/test/std/utilities/variant/variant.variant/variant_void.fail.cpp
new file mode 100644
index 000000000000..3d0da5620b50
--- /dev/null
+++ b/test/std/utilities/variant/variant.variant/variant_void.fail.cpp
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+
+#include <variant>
+#include <type_traits>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+#include "test_convertible.hpp"
+
+int main()
+{
+ // expected-error@variant:* 3 {{static_assert failed}}
+ std::variant<int, void> v; // expected-note {{requested here}}
+ std::variant<int, const void> v2; // expected-note {{requested here}}
+ std::variant<const volatile void, int> v3; // expected-note {{requested here}}
+}
diff --git a/test/std/utilities/variant/variant.visit/visit.pass.cpp b/test/std/utilities/variant/variant.visit/visit.pass.cpp
new file mode 100644
index 000000000000..46d225883ae9
--- /dev/null
+++ b/test/std/utilities/variant/variant.visit/visit.pass.cpp
@@ -0,0 +1,291 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+// template <class Visitor, class... Variants>
+// constexpr see below visit(Visitor&& vis, Variants&&... vars);
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+#include "test_macros.h"
+#include "type_id.h"
+#include "variant_test_helpers.hpp"
+
+enum CallType : unsigned {
+ CT_None,
+ CT_NonConst = 1,
+ CT_Const = 2,
+ CT_LValue = 4,
+ CT_RValue = 8
+};
+
+inline constexpr CallType operator|(CallType LHS, CallType RHS) {
+ return static_cast<CallType>(static_cast<unsigned>(LHS) |
+ static_cast<unsigned>(RHS));
+}
+
+struct ForwardingCallObject {
+
+ template <class... Args> bool operator()(Args &&...) & {
+ set_call<Args &&...>(CT_NonConst | CT_LValue);
+ return true;
+ }
+
+ template <class... Args> bool operator()(Args &&...) const & {
+ set_call<Args &&...>(CT_Const | CT_LValue);
+ return true;
+ }
+
+ // Don't allow the call operator to be invoked as an rvalue.
+ template <class... Args> bool operator()(Args &&...) && {
+ set_call<Args &&...>(CT_NonConst | CT_RValue);
+ return true;
+ }
+
+ template <class... Args> bool operator()(Args &&...) const && {
+ set_call<Args &&...>(CT_Const | CT_RValue);
+ return true;
+ }
+
+ template <class... Args> static void set_call(CallType type) {
+ assert(last_call_type == CT_None);
+ assert(last_call_args == nullptr);
+ last_call_type = type;
+ last_call_args = std::addressof(makeArgumentID<Args...>());
+ }
+
+ template <class... Args> static bool check_call(CallType type) {
+ bool result = last_call_type == type && last_call_args &&
+ *last_call_args == makeArgumentID<Args...>();
+ last_call_type = CT_None;
+ last_call_args = nullptr;
+ return result;
+ }
+
+ static CallType last_call_type;
+ static const TypeID *last_call_args;
+};
+
+CallType ForwardingCallObject::last_call_type = CT_None;
+const TypeID *ForwardingCallObject::last_call_args = nullptr;
+
+void test_call_operator_forwarding() {
+ using Fn = ForwardingCallObject;
+ Fn obj{};
+ const Fn &cobj = obj;
+ { // test call operator forwarding - single variant, single arg
+ using V = std::variant<int>;
+ V v(42);
+ std::visit(obj, v);
+ assert(Fn::check_call<int &>(CT_NonConst | CT_LValue));
+ std::visit(cobj, v);
+ assert(Fn::check_call<int &>(CT_Const | CT_LValue));
+ std::visit(std::move(obj), v);
+ assert(Fn::check_call<int &>(CT_NonConst | CT_RValue));
+ std::visit(std::move(cobj), v);
+ assert(Fn::check_call<int &>(CT_Const | CT_RValue));
+ }
+ { // test call operator forwarding - single variant, multi arg
+ using V = std::variant<int, long, double>;
+ V v(42l);
+ std::visit(obj, v);
+ assert(Fn::check_call<long &>(CT_NonConst | CT_LValue));
+ std::visit(cobj, v);
+ assert(Fn::check_call<long &>(CT_Const | CT_LValue));
+ std::visit(std::move(obj), v);
+ assert(Fn::check_call<long &>(CT_NonConst | CT_RValue));
+ std::visit(std::move(cobj), v);
+ assert(Fn::check_call<long &>(CT_Const | CT_RValue));
+ }
+ { // test call operator forwarding - multi variant, multi arg
+ using V = std::variant<int, long, double>;
+ using V2 = std::variant<int *, std::string>;
+ V v(42l);
+ V2 v2("hello");
+ std::visit(obj, v, v2);
+ assert((Fn::check_call<long &, std::string &>(CT_NonConst | CT_LValue)));
+ std::visit(cobj, v, v2);
+ assert((Fn::check_call<long &, std::string &>(CT_Const | CT_LValue)));
+ std::visit(std::move(obj), v, v2);
+ assert((Fn::check_call<long &, std::string &>(CT_NonConst | CT_RValue)));
+ std::visit(std::move(cobj), v, v2);
+ assert((Fn::check_call<long &, std::string &>(CT_Const | CT_RValue)));
+ }
+}
+
+void test_argument_forwarding() {
+ using Fn = ForwardingCallObject;
+ Fn obj{};
+ const auto Val = CT_LValue | CT_NonConst;
+ { // single argument - value type
+ using V = std::variant<int>;
+ V v(42);
+ const V &cv = v;
+ std::visit(obj, v);
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<const int &>(Val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int &&>(Val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<const int &&>(Val));
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ { // single argument - lvalue reference
+ using V = std::variant<int &>;
+ int x = 42;
+ V v(x);
+ const V &cv = v;
+ std::visit(obj, v);
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<int &>(Val));
+ }
+ { // single argument - rvalue reference
+ using V = std::variant<int &&>;
+ int x = 42;
+ V v(std::move(x));
+ const V &cv = v;
+ std::visit(obj, v);
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, cv);
+ assert(Fn::check_call<int &>(Val));
+ std::visit(obj, std::move(v));
+ assert(Fn::check_call<int &&>(Val));
+ std::visit(obj, std::move(cv));
+ assert(Fn::check_call<int &&>(Val));
+ }
+ { // multi argument - multi variant
+ using S = const std::string &;
+ using V = std::variant<int, S, long &&>;
+ const std::string str = "hello";
+ long l = 43;
+ V v1(42);
+ const V &cv1 = v1;
+ V v2(str);
+ const V &cv2 = v2;
+ V v3(std::move(l));
+ const V &cv3 = v3;
+ std::visit(obj, v1, v2, v3);
+ assert((Fn::check_call<int &, S, long &>(Val)));
+ std::visit(obj, cv1, cv2, std::move(v3));
+ assert((Fn::check_call<const int &, S, long &&>(Val)));
+ }
+#endif
+}
+
+struct ReturnFirst {
+ template <class... Args> constexpr int operator()(int f, Args &&...) const {
+ return f;
+ }
+};
+
+struct ReturnArity {
+ template <class... Args> constexpr int operator()(Args &&...) const {
+ return sizeof...(Args);
+ }
+};
+
+void test_constexpr() {
+ constexpr ReturnFirst obj{};
+ constexpr ReturnArity aobj{};
+ {
+ using V = std::variant<int>;
+ constexpr V v(42);
+ static_assert(std::visit(obj, v) == 42, "");
+ }
+ {
+ using V = std::variant<short, long, char>;
+ constexpr V v(42l);
+ static_assert(std::visit(obj, v) == 42, "");
+ }
+ {
+ using V1 = std::variant<int>;
+ using V2 = std::variant<int, char *, long long>;
+ using V3 = std::variant<bool, int, int>;
+ constexpr V1 v1;
+ constexpr V2 v2(nullptr);
+ constexpr V3 v3;
+ static_assert(std::visit(aobj, v1, v2, v3) == 3, "");
+ }
+ {
+ using V1 = std::variant<int>;
+ using V2 = std::variant<int, char *, long long>;
+ using V3 = std::variant<void *, int, int>;
+ constexpr V1 v1;
+ constexpr V2 v2(nullptr);
+ constexpr V3 v3;
+ static_assert(std::visit(aobj, v1, v2, v3) == 3, "");
+ }
+}
+
+void test_exceptions() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ ReturnArity obj{};
+ auto test = [&](auto &&... args) {
+ try {
+ std::visit(obj, args...);
+ } catch (const std::bad_variant_access &) {
+ return true;
+ } catch (...) {
+ }
+ return false;
+ };
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ V v;
+ makeEmpty(v);
+ assert(test(v));
+ }
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ using V2 = std::variant<long, std::string, void *>;
+ V v;
+ makeEmpty(v);
+ V2 v2("hello");
+ assert(test(v, v2));
+ }
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ using V2 = std::variant<long, std::string, void *>;
+ V v;
+ makeEmpty(v);
+ V2 v2("hello");
+ assert(test(v2, v));
+ }
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ using V2 = std::variant<long, std::string, void *, MakeEmptyT>;
+ V v;
+ makeEmpty(v);
+ V2 v2;
+ makeEmpty(v2);
+ assert(test(v, v2));
+ }
+#endif
+}
+
+int main() {
+ test_call_operator_forwarding();
+ test_argument_forwarding();
+ test_constexpr();
+ test_exceptions();
+}