summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2019-07-03 19:21:40 +0000
committerEric Fiselier <eric@efcs.ca>2019-07-03 19:21:40 +0000
commit78af2bfb2f1e38c398b3dfdd9927a2fb2652f3c8 (patch)
tree3864ecbd71828e5a9b4ca89612fb6cd82fbac38a
parentba4d4df3ab1382dd07d31fa50d5ab72ba11e76b8 (diff)
Fix tuple's conditionally explicit constructors for very weird user
types. It seems some people like to write types that can explicitly convert to anything, but cannot be used to explicitly construct anything. This patch makes tuple tolerate such types, as is required by the standard. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@365074 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/tuple11
-rw-r--r--test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp14
2 files changed, 24 insertions, 1 deletions
diff --git a/include/tuple b/include/tuple
index c192d100e..de30e86c7 100644
--- a/include/tuple
+++ b/include/tuple
@@ -521,6 +521,13 @@ class _LIBCPP_TEMPLATE_VIS tuple
template <class ..._Args>
static constexpr bool __enable_implicit() {
return
+ __tuple_constructible<
+ tuple<_Args...>,
+ typename __make_tuple_types<tuple,
+ sizeof...(_Args) < sizeof...(_Tp) ?
+ sizeof...(_Args) :
+ sizeof...(_Tp)>::type
+ >::value &&
__tuple_convertible<
tuple<_Args...>,
typename __make_tuple_types<tuple,
@@ -547,7 +554,8 @@ class _LIBCPP_TEMPLATE_VIS tuple
{
template <class _Tuple>
static constexpr bool __enable_implicit() {
- return __tuple_convertible<_Tuple, tuple>::value;
+ return __tuple_constructible<_Tuple, tuple>::value
+ && __tuple_convertible<_Tuple, tuple>::value;
}
template <class _Tuple>
@@ -577,6 +585,7 @@ class _LIBCPP_TEMPLATE_VIS tuple
template <class _Tuple>
static constexpr bool __enable_implicit() {
return _And<
+ __tuple_constructible<_Tuple, tuple>,
__tuple_convertible<_Tuple, tuple>,
_PreferTupleLikeConstructor<_Tuple>
>::value;
diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
index f34320144..2c24f786a 100644
--- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
+++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
@@ -46,6 +46,20 @@ struct D
explicit D(int i) : B(i) {}
};
+struct BonkersBananas {
+ template <class T>
+ operator T() &&;
+ template <class T, class = void>
+ explicit operator T() && = delete;
+};
+
+void test_bonkers_bananas_conversion() {
+ using ReturnType = std::tuple<int, int>;
+ static_assert(std::is_convertible<BonkersBananas, ReturnType>(), "");
+ static_assert(!std::is_constructible<ReturnType, BonkersBananas>(), "");
+
+}
+
int main(int, char**)
{
{