//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // template // template // constexpr explicit(see below) // tuple::tuple(allocator_arg_t, const Alloc& a, const pair&& u); // Constraints: // - sizeof...(Types) is 2 and // - is_constructible_v(FWD(u)))> is true and // - is_constructible_v(FWD(u)))> is true. // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 #include #include #include #include "copy_move_types.h" #include "test_allocator.h" // test constraints // sizeof...(Types) == 2 static_assert(std::is_constructible_v, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert(!std::is_constructible_v< std::tuple, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert(!std::is_constructible_v< std::tuple, std::allocator_arg_t, test_allocator, const std::pair&&>); // test constraints // is_constructible_v(FWD(u)))> is true and // is_constructible_v(FWD(u)))> is true. static_assert(std::is_constructible_v, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert(!std::is_constructible_v< std::tuple, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert(!std::is_constructible_v< std::tuple, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert(!std::is_constructible_v< std::tuple, std::allocator_arg_t, test_allocator, const std::pair&&>); // test: The expression inside explicit is equivalent to: // !is_convertible_v(FWD(u))), T0> || // !is_convertible_v(FWD(u))), T1> static_assert( ImplicitlyConstructible< std::tuple, ConvertibleFrom>, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert( !ImplicitlyConstructible, ExplicitConstructibleFrom>, std::allocator_arg_t, test_allocator, const std::pair&&>); static_assert( !ImplicitlyConstructible, ConvertibleFrom>, std::allocator_arg_t, test_allocator, const std::pair&&>); constexpr bool test() { // test implicit conversions. { const std::pair p{1, 2}; std::tuple, ConvertibleFrom> t = {std::allocator_arg, test_allocator{}, std::move(p)}; assert(std::get<0>(t).v.val == 1); assert(std::get<1>(t).v == 2); assert(std::get<0>(t).alloc_constructed); assert(std::get<1>(t).alloc_constructed); } // test explicit conversions. { const std::pair p{1, 2}; std::tuple, ExplicitConstructibleFrom> t{ std::allocator_arg, test_allocator{}, std::move(p)}; assert(std::get<0>(t).v.val == 1); assert(std::get<1>(t).v == 2); assert(std::get<0>(t).alloc_constructed); assert(std::get<1>(t).alloc_constructed); } // non const overload should be called { const std::pair p; std::tuple, TracedCopyMove> t = {std::allocator_arg, test_allocator{}, std::move(p)}; assert(constMoveCtrCalled(std::get<0>(t).v)); assert(constMoveCtrCalled(std::get<1>(t))); assert(std::get<0>(t).alloc_constructed); assert(std::get<1>(t).alloc_constructed); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }