diff options
Diffstat (limited to 'test/std/utilities/utility')
43 files changed, 1451 insertions, 519 deletions
diff --git a/test/std/utilities/utility/exchange/exchange.pass.cpp b/test/std/utilities/utility/exchange/exchange.pass.cpp index 5ef0ac3b09f52..2d01d6c8c8afb 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 0000000000000..a3bb890482ef5 --- /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 94575485df047..afff8d627fade 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&); +A source() noexcept {return A();} +const A csource() noexcept {return A();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -four test(A&&); -eight test(const A&&); - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +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(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(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(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(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, ""); + 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())), ""); -#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, "" ); +#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/forward3.fail.cpp b/test/std/utilities/utility/forward/forward3.fail.cpp deleted file mode 100644 index 7e1e9b38fdc2d..0000000000000 --- a/test/std/utilities/utility/forward/forward3.fail.cpp +++ /dev/null @@ -1,24 +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() -{ - std::forward<A&>(csource()); // error -} diff --git a/test/std/utilities/utility/forward/forward4.fail.cpp b/test/std/utilities/utility/forward/forward4.fail.cpp deleted file mode 100644 index 276506f811b5f..0000000000000 --- a/test/std/utilities/utility/forward/forward4.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>(ca); // error -} 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 86c2b5651b90e..0000000000000 --- 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/forward6.fail.cpp b/test/std/utilities/utility/forward/forward6.fail.cpp deleted file mode 100644 index 1f4b37d946caa..0000000000000 --- a/test/std/utilities/utility/forward/forward6.fail.cpp +++ /dev/null @@ -1,22 +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 -{ -}; - -int main() -{ - A a; - std::forward(a); // 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 0000000000000..7e141bad94e81 --- /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 520bf5e5b6a18..bd2126cbaee42 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 0000000000000..e2edc2a2afadd --- /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 fa15553f669f0..0000000000000 --- 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 5e7623a1bd19a..0000000000000 --- 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 2043f3d4bde7a..0000000000000 --- 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 84c83ae48f8ac..0000000000000 --- 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 5eeca89abe36a..0000000000000 --- 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 9ef7bcff2ba83..c09c8815e16f4 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 edd2f3d0752fc..5c38318d26da1 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 47b4c06134d97..2f8b6c1e8497d 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 aa5ca530913c0..0601e4e73a74a 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 8c7dee2499ddc..1ef2d9402fc31 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 fdef5961437a5..132443f66a7c5 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 0000000000000..3f70663100027 --- /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 0000000000000..2623b800fff7b --- /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 a753ee520dfab..38089200e4daa 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 a200390f4882f..76dfc3f65a237 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 0000000000000..ef7bebcf5c295 --- /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 2041b39c2dc91..bf19d1abe4c52 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 0000000000000..8c56c20034606 --- /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 286cce47f0503..ade8130d78224 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/forward/forward1.fail.cpp b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.pass.cpp index 43884d54bf86b..fbf461f9b7e0c 100644 --- a/test/std/utilities/utility/forward/forward1.fail.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/const_pair_U_V_cxx03.pass.cpp @@ -7,18 +7,23 @@ // //===----------------------------------------------------------------------===// -// test forward +// <utility> -#include <utility> +// template <class T1, class T2> struct pair -struct A -{ -}; +// template <class U, class V> pair(const pair<U, V>& p); -A source() {return A();} -const A csource() {return A();} +#include <utility> +#include <cassert> int main() { - std::forward<A&>(source()); // error + { + 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 1117db3297b85..1003f3c8b68f6 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 97182d24d0217..ace00a16f21e0 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/forward/forward2.fail.cpp b/test/std/utilities/utility/pairs/pairs.pair/dtor.pass.cpp index 9ff07233fee82..2d87e7abababb 100644 --- a/test/std/utilities/utility/forward/forward2.fail.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/dtor.pass.cpp @@ -7,19 +7,26 @@ // //===----------------------------------------------------------------------===// -// test forward +// UNSUPPORTED: c++98, c++03 -#include <utility> +// <utility> -struct A -{ -}; +// template <class T1, class T2> struct pair + +// ~pair() + + +#include <utility> +#include <type_traits> +#include <string> +#include <cassert> -A source() {return A();} -const A csource() {return A();} +#include "test_macros.h" int main() { - const A ca = A(); - std::forward<A&>(ca); // error + 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 06cb5e5658c90..99e00b025da22 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 0000000000000..3704dcc32edc4 --- /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 5fb6c98979b5d..2856190841c0e 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 0000000000000..1331a31536419 --- /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 dfea61eeacdb0..95b1f66d64aa6 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 53cf56700df88..200f044c6359d 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 9ba8532ab29ec..3b994dfd4dfeb 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 4a6d71e7b9c85..3586243f8bacf 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 d9d8f27b5225c..62fa942479469 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 0000000000000..e87c6f399e93f --- /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)>)); + } +} |
