diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-04-19 01:19:25 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-04-19 01:19:25 +0000 |
commit | 9795699a7282a29d1a0a5c202209c6e2a4cc5539 (patch) | |
tree | 8a0a829dc3e86541e2bd74b35b316bed3c1e62f1 /libcxx/test/std | |
parent | 167c7962321f063a713957296e37e5b1903cf007 (diff) | |
download | bcm5719-llvm-9795699a7282a29d1a0a5c202209c6e2a4cc5539.tar.gz bcm5719-llvm-9795699a7282a29d1a0a5c202209c6e2a4cc5539.zip |
Make tuples constructors conditionally EXPLICIT. See N4387
llvm-svn: 266703
Diffstat (limited to 'libcxx/test/std')
11 files changed, 285 insertions, 3 deletions
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp index 394af00231e..e174e9b321b 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp @@ -73,9 +73,18 @@ void test_uses_allocator_sfinae_evaluation() } } +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + int main() { { + std::tuple<Explicit> t{std::allocator_arg, std::allocator<void>{}, 42}; + assert(std::get<0>(t).value == 42); + } + { std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0)); assert(std::get<0>(t) == 0); } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp new file mode 100644 index 00000000000..b28ad6dab5a --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc> +// EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> +#include <cassert> + +struct ExplicitCopy { + explicit ExplicitCopy(ExplicitCopy const&) {} + explicit ExplicitCopy(int) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicity_copy_test() { + ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} +int main() +{ + const_explicit_copy_test(); + non_const_explicity_copy_test(); +} diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp index 0f68926376f..73d53a4c0e2 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp @@ -17,15 +17,37 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = {std::allocator_arg, std::allocator<void>{}, 0}; + } + { std::tuple<int> t(std::allocator_arg, A1<int>(), 3); assert(std::get<0>(t) == 3); } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp new file mode 100644 index 00000000000..ccf08833b53 --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...> const&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} + +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicit_copy_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp index 8acfde7a98e..36d9f32879c 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp @@ -17,12 +17,23 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -66,4 +77,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1) == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp new file mode 100644 index 00000000000..d3539cebf95 --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> explicit_move_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp index c862d3b64d5..d3a6add5da6 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp @@ -40,6 +40,16 @@ struct D explicit D(int i) : B(i) {} }; +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp index 00e2af265b3..b72f0fc2efe 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp @@ -19,9 +19,30 @@ #include <string> #include <cassert> +struct ExplicitCopy { + ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy() { + const ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + + +std::tuple<ExplicitCopy> non_const_explicit_copy() { + ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> const_explicit_copy_no_brace() { + const ExplicitCopy e(42); + return e; + // expected-error@-1 {{no viable conversion}} +} + int main() { - { - std::tuple<int*> t = 0; - } } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp index bbadf8de160..e787e877722 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp @@ -53,9 +53,36 @@ struct NoValueCtorEmpty { static_assert(never<T>::value, "This should not be instantiated"); } }; + +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy3() { + const ImplicitCopy i(42); + return i; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = 0; + } + { std::tuple<int> t(2); assert(std::get<0>(t) == 2); } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp index 5ad4f9227f4..e176bc84f79 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp @@ -20,6 +20,16 @@ #include <string> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -115,4 +125,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1).id_ == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2(t1); + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = t1; + assert(std::get<0>(t2).value == 42); + } } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp index 3a6abd3a95a..8423f5d0145 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp @@ -20,6 +20,16 @@ #include <memory> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2(std::move(t1)); + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = std::move(t1); + assert(std::get<0>(t2).value == 42); + } } |