mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 15:24:07 +08:00
re PR libstdc++/50159 ([C++0x] tuple_cat only accepts two arguments)
2011-09-11 Daniel Krugler <daniel.kruegler@googlemail.com> PR libstdc++/50159 * include/std/tuple (tuple_cat): Reimplement according to the resolution of LWG 1385. * include/std/type_traits: Define __and_ and __or_ for zero arguments too; minor tweaks. * testsuite/20_util/tuple/creation_functions/tuple_cat.cc: New. * testsuite/20_util/tuple/creation_functions/constexpr.cc: Disable for now tuple_cat test. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error line numbers. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. * doc/xml/manual/status_cxx200x.xml: Update. From-SVN: r178770
This commit is contained in:
parent
fa11ae6c72
commit
ac65b7d221
@ -1,3 +1,20 @@
|
||||
2011-09-11 Daniel Krugler <daniel.kruegler@googlemail.com>
|
||||
|
||||
PR libstdc++/50159
|
||||
* include/std/tuple (tuple_cat): Reimplement according to the
|
||||
resolution of LWG 1385.
|
||||
* include/std/type_traits: Define __and_ and __or_ for zero
|
||||
arguments too; minor tweaks.
|
||||
* testsuite/20_util/tuple/creation_functions/tuple_cat.cc: New.
|
||||
* testsuite/20_util/tuple/creation_functions/constexpr.cc: Disable
|
||||
for now tuple_cat test.
|
||||
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error
|
||||
line numbers.
|
||||
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise.
|
||||
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
|
||||
Likewise.
|
||||
* doc/xml/manual/status_cxx200x.xml: Update.
|
||||
|
||||
2011-09-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* include/std/tuple: Use everywhere std::size_t... instead of int...
|
||||
|
@ -443,11 +443,10 @@ particular release.
|
||||
<entry/>
|
||||
</row>
|
||||
<row>
|
||||
<?dbhtml bgcolor="#B0B0B0" ?>
|
||||
<entry>20.4.2.4</entry>
|
||||
<entry>Tuple creation functions</entry>
|
||||
<entry>Partial</entry>
|
||||
<entry><code>tuple_cat</code> should be a single variadic signature (DR 1385)</entry>
|
||||
<entry>Y</entry>
|
||||
<entry/>
|
||||
</row>
|
||||
<row>
|
||||
<entry>20.4.2.5</entry>
|
||||
|
@ -876,108 +876,184 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
forward_as_tuple(_Elements&&... __args) noexcept
|
||||
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
|
||||
|
||||
template<std::size_t...> struct __index_holder { };
|
||||
|
||||
template<std::size_t __i, typename _IdxHolder, typename... _Elements>
|
||||
struct __index_holder_impl;
|
||||
template<typename, std::size_t> struct array;
|
||||
|
||||
template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
|
||||
typename... _Elements>
|
||||
struct __index_holder_impl<__i, __index_holder<_Indexes...>,
|
||||
_IdxHolder, _Elements...>
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
_Tp& get(array<_Tp, _Nm>&) noexcept;
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
_Tp&& get(array<_Tp, _Nm>&&) noexcept;
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
const _Tp& get(const array<_Tp, _Nm>&) noexcept;
|
||||
|
||||
template<typename>
|
||||
struct __is_tuple_like_impl : false_type
|
||||
{ };
|
||||
|
||||
template<typename... _Tps>
|
||||
struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
|
||||
{ };
|
||||
|
||||
template<typename _T1, typename _T2>
|
||||
struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
|
||||
{ };
|
||||
|
||||
template<typename _Tp, std::size_t _Nm>
|
||||
struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
|
||||
{ };
|
||||
|
||||
// Internal type trait that allows us to sfinae-protect tuple_cat.
|
||||
template<typename _Tp>
|
||||
struct __is_tuple_like
|
||||
: public __is_tuple_like_impl<typename std::remove_cv
|
||||
<typename std::remove_reference<_Tp>::type>::type>::type
|
||||
{ };
|
||||
|
||||
// Stores a tuple of indices. Also used by bind() to extract the elements
|
||||
// in a tuple.
|
||||
template<std::size_t... _Indexes>
|
||||
struct _Index_tuple
|
||||
{
|
||||
typedef typename __index_holder_impl<__i + 1,
|
||||
__index_holder<_Indexes..., __i>,
|
||||
_Elements...>::type type;
|
||||
typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
|
||||
};
|
||||
|
||||
template<std::size_t __i, std::size_t... _Indexes>
|
||||
struct __index_holder_impl<__i, __index_holder<_Indexes...> >
|
||||
{ typedef __index_holder<_Indexes...> type; };
|
||||
|
||||
template<typename... _Elements>
|
||||
struct __make_index_holder
|
||||
: __index_holder_impl<0, __index_holder<>, _Elements...> { };
|
||||
|
||||
template<typename... _TElements, std::size_t... _TIdx,
|
||||
typename... _UElements, std::size_t... _UIdx>
|
||||
inline constexpr tuple<_TElements..., _UElements...>
|
||||
__tuple_cat_helper(const tuple<_TElements...>& __t,
|
||||
const __index_holder<_TIdx...>&,
|
||||
const tuple<_UElements...>& __u,
|
||||
const __index_holder<_UIdx...>&)
|
||||
{ return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
|
||||
get<_UIdx>(__u)...); }
|
||||
|
||||
template<typename... _TElements, std::size_t... _TIdx,
|
||||
typename... _UElements, std::size_t... _UIdx>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
__tuple_cat_helper(tuple<_TElements...>&& __t,
|
||||
const __index_holder<_TIdx...>&,
|
||||
const tuple<_UElements...>& __u,
|
||||
const __index_holder<_UIdx...>&)
|
||||
{ return tuple<_TElements..., _UElements...>
|
||||
(std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
|
||||
|
||||
template<typename... _TElements, std::size_t... _TIdx,
|
||||
typename... _UElements, std::size_t... _UIdx>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
__tuple_cat_helper(const tuple<_TElements...>& __t,
|
||||
const __index_holder<_TIdx...>&,
|
||||
tuple<_UElements...>&& __u,
|
||||
const __index_holder<_UIdx...>&)
|
||||
{ return tuple<_TElements..., _UElements...>
|
||||
(get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); }
|
||||
|
||||
template<typename... _TElements, std::size_t... _TIdx,
|
||||
typename... _UElements, std::size_t... _UIdx>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
__tuple_cat_helper(tuple<_TElements...>&& __t,
|
||||
const __index_holder<_TIdx...>&,
|
||||
tuple<_UElements...>&& __u,
|
||||
const __index_holder<_UIdx...>&)
|
||||
{ return tuple<_TElements..., _UElements...>
|
||||
(std::forward<_TElements>(get<_TIdx>(__t))...,
|
||||
std::forward<_UElements>(get<_UIdx>(__u))...); }
|
||||
|
||||
template<typename... _TElements, typename... _UElements>
|
||||
inline constexpr tuple<_TElements..., _UElements...>
|
||||
tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
|
||||
// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
|
||||
template<std::size_t _Num>
|
||||
struct _Build_index_tuple
|
||||
{
|
||||
return __tuple_cat_helper(__t, typename
|
||||
__make_index_holder<_TElements...>::type(),
|
||||
__u, typename
|
||||
__make_index_holder<_UElements...>::type());
|
||||
}
|
||||
typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type;
|
||||
};
|
||||
|
||||
template<typename... _TElements, typename... _UElements>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
|
||||
template<>
|
||||
struct _Build_index_tuple<0>
|
||||
{
|
||||
return __tuple_cat_helper(std::move(__t), typename
|
||||
__make_index_holder<_TElements...>::type(),
|
||||
__u, typename
|
||||
__make_index_holder<_UElements...>::type());
|
||||
}
|
||||
typedef _Index_tuple<> __type;
|
||||
};
|
||||
|
||||
template<typename... _TElements, typename... _UElements>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
|
||||
{
|
||||
return __tuple_cat_helper(__t, typename
|
||||
__make_index_holder<_TElements...>::type(),
|
||||
std::move(__u), typename
|
||||
__make_index_holder<_UElements...>::type());
|
||||
}
|
||||
template<std::size_t, typename, typename, std::size_t>
|
||||
struct __make_tuple_impl;
|
||||
|
||||
template<typename... _TElements, typename... _UElements>
|
||||
inline tuple<_TElements..., _UElements...>
|
||||
tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
|
||||
template<std::size_t _Idx, typename _Tuple, typename... _Tp,
|
||||
std::size_t _Nm>
|
||||
struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
|
||||
{
|
||||
return __tuple_cat_helper(std::move(__t), typename
|
||||
__make_index_holder<_TElements...>::type(),
|
||||
std::move(__u), typename
|
||||
__make_index_holder<_UElements...>::type());
|
||||
typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
|
||||
typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
|
||||
__type;
|
||||
};
|
||||
|
||||
template<std::size_t _Nm, typename _Tuple, typename... _Tp>
|
||||
struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
|
||||
{
|
||||
typedef tuple<_Tp...> __type;
|
||||
};
|
||||
|
||||
template<typename _Tuple>
|
||||
struct __do_make_tuple
|
||||
: public __make_tuple_impl<0, tuple<>, _Tuple,
|
||||
std::tuple_size<_Tuple>::value>
|
||||
{ };
|
||||
|
||||
// Returns the std::tuple equivalent of a tuple-like type.
|
||||
template<typename _Tuple>
|
||||
struct __make_tuple
|
||||
: public __do_make_tuple<typename std::remove_cv
|
||||
<typename std::remove_reference<_Tuple>::type>::type>
|
||||
{ };
|
||||
|
||||
// Combines several std::tuple's into a single one.
|
||||
template<typename...>
|
||||
struct __combine_tuples;
|
||||
|
||||
template<>
|
||||
struct __combine_tuples<>
|
||||
{
|
||||
typedef tuple<> __type;
|
||||
};
|
||||
|
||||
template<typename... _Ts>
|
||||
struct __combine_tuples<tuple<_Ts...>>
|
||||
{
|
||||
typedef tuple<_Ts...> __type;
|
||||
};
|
||||
|
||||
template<typename... _T1s, typename... _T2s, typename... _Rem>
|
||||
struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
|
||||
{
|
||||
typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
|
||||
_Rem...>::__type __type;
|
||||
};
|
||||
|
||||
// Computes the result type of tuple_cat given a set of tuple-like types.
|
||||
template<typename... _Tpls>
|
||||
struct __tuple_cat_result
|
||||
{
|
||||
typedef typename __combine_tuples
|
||||
<typename __make_tuple<_Tpls>::__type...>::__type __type;
|
||||
};
|
||||
|
||||
// Helper to determine the index set for the first tuple-like
|
||||
// type of a given set.
|
||||
template<typename...>
|
||||
struct __make_1st_indices;
|
||||
|
||||
template<>
|
||||
struct __make_1st_indices<>
|
||||
{
|
||||
typedef std::_Index_tuple<> __type;
|
||||
};
|
||||
|
||||
template<typename _Tp, typename... _Tpls>
|
||||
struct __make_1st_indices<_Tp, _Tpls...>
|
||||
{
|
||||
typedef typename std::_Build_index_tuple<std::tuple_size<
|
||||
typename std::remove_reference<_Tp>::type>::value>::__type __type;
|
||||
};
|
||||
|
||||
// Performs the actual concatenation by step-wise expanding tuple-like
|
||||
// objects into the elements, which are finally forwarded into the
|
||||
// result tuple.
|
||||
template<typename _Ret, typename _Indices, typename... _Tpls>
|
||||
struct __tuple_concater;
|
||||
|
||||
template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
|
||||
struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
|
||||
{
|
||||
template<typename... _Us>
|
||||
static _Ret
|
||||
_S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
|
||||
{
|
||||
typedef typename __make_1st_indices<_Tpls...>::__type __idx;
|
||||
typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
|
||||
return __next::_S_do(std::forward<_Tpls>(__tps)...,
|
||||
std::forward<_Us>(__us)...,
|
||||
std::get<_Is>(std::forward<_Tp>(__tp))...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Ret>
|
||||
struct __tuple_concater<_Ret, std::_Index_tuple<>>
|
||||
{
|
||||
template<typename... _Us>
|
||||
static _Ret
|
||||
_S_do(_Us&&... __us)
|
||||
{
|
||||
return _Ret(std::forward<_Us>(__us)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... _Tpls>
|
||||
inline typename
|
||||
std::enable_if<__and_<__is_tuple_like<_Tpls>...>::value,
|
||||
typename __tuple_cat_result<_Tpls...>::__type>::type
|
||||
tuple_cat(_Tpls&&... __tpls)
|
||||
{
|
||||
typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
|
||||
typedef typename __make_1st_indices<_Tpls...>::__type __idx;
|
||||
typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
|
||||
return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
|
||||
}
|
||||
|
||||
template<typename... _Elements>
|
||||
@ -1007,29 +1083,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<typename... _Types, typename _Alloc>
|
||||
struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
|
||||
|
||||
/**
|
||||
* Stores a tuple of indices. Used by bind() to extract the elements
|
||||
* in a tuple.
|
||||
*/
|
||||
template<std::size_t... _Indexes>
|
||||
struct _Index_tuple
|
||||
{
|
||||
typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
|
||||
};
|
||||
|
||||
/// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
|
||||
template<std::size_t _Num>
|
||||
struct _Build_index_tuple
|
||||
{
|
||||
typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct _Build_index_tuple<0>
|
||||
{
|
||||
typedef _Index_tuple<> __type;
|
||||
};
|
||||
|
||||
// See stl_pair.h...
|
||||
template<class _T1, class _T2>
|
||||
template<typename _Tp, typename... _Args>
|
||||
|
@ -45,23 +45,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
* @addtogroup metaprogramming
|
||||
* @{
|
||||
*/
|
||||
struct __sfinae_types
|
||||
{
|
||||
typedef char __one;
|
||||
typedef struct { char __arr[2]; } __two;
|
||||
};
|
||||
|
||||
/// integral_constant
|
||||
template<typename _Tp, _Tp __v>
|
||||
struct integral_constant
|
||||
{
|
||||
static constexpr _Tp value = __v;
|
||||
typedef _Tp value_type;
|
||||
typedef integral_constant<_Tp, __v> type;
|
||||
constexpr operator value_type() { return value; }
|
||||
};
|
||||
|
||||
/// typedef for true_type
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
|
||||
/// typedef for false_type
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
template<typename _Tp, _Tp __v>
|
||||
constexpr _Tp integral_constant<_Tp, __v>::value;
|
||||
|
||||
// Meta programming helper types.
|
||||
|
||||
template<bool, typename, typename>
|
||||
struct conditional;
|
||||
|
||||
template<typename _Tp, _Tp>
|
||||
struct integral_constant;
|
||||
|
||||
template<typename...>
|
||||
struct __or_;
|
||||
|
||||
template<>
|
||||
struct __or_<>
|
||||
: public false_type
|
||||
{ };
|
||||
|
||||
template<typename _B1>
|
||||
struct __or_<_B1>
|
||||
: public _B1
|
||||
@ -80,6 +96,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<typename...>
|
||||
struct __and_;
|
||||
|
||||
template<>
|
||||
struct __and_<>
|
||||
: public true_type
|
||||
{ };
|
||||
|
||||
template<typename _B1>
|
||||
struct __and_<_B1>
|
||||
: public _B1
|
||||
@ -100,26 +121,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: public integral_constant<bool, !_Pp::value>
|
||||
{ };
|
||||
|
||||
// helper class.
|
||||
|
||||
/// integral_constant
|
||||
template<typename _Tp, _Tp __v>
|
||||
struct integral_constant
|
||||
{
|
||||
static constexpr _Tp value = __v;
|
||||
typedef _Tp value_type;
|
||||
typedef integral_constant<_Tp, __v> type;
|
||||
constexpr operator value_type() { return value; }
|
||||
};
|
||||
|
||||
/// typedef for true_type
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
|
||||
/// typedef for false_type
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
template<typename _Tp, _Tp __v>
|
||||
constexpr _Tp integral_constant<_Tp, __v>::value;
|
||||
struct __sfinae_types
|
||||
{
|
||||
typedef char __one;
|
||||
typedef struct { char __arr[2]; } __two;
|
||||
};
|
||||
|
||||
// primary type categories.
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 1725 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 1731 }
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
@ -48,5 +48,5 @@ void test01()
|
||||
// { dg-error "required from here" "" { target *-*-* } 40 }
|
||||
// { dg-error "required from here" "" { target *-*-* } 42 }
|
||||
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1511 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1475 }
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1517 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1481 }
|
||||
|
@ -48,5 +48,5 @@ void test01()
|
||||
// { dg-error "required from here" "" { target *-*-* } 40 }
|
||||
// { dg-error "required from here" "" { target *-*-* } 42 }
|
||||
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1435 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1399 }
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1441 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1405 }
|
||||
|
@ -63,6 +63,7 @@ test_get()
|
||||
}
|
||||
|
||||
// tuple_cat
|
||||
#if 0
|
||||
void
|
||||
test_tuple_cat()
|
||||
{
|
||||
@ -73,7 +74,7 @@ test_tuple_cat()
|
||||
constexpr tuple_type2 t2 { 55, 99, 77.77 };
|
||||
constexpr auto cat1 = std::tuple_cat(t1, t2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
main()
|
||||
@ -84,7 +85,9 @@ main()
|
||||
|
||||
test_get();
|
||||
|
||||
#if 0
|
||||
test_tuple_cat();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,131 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Tuple
|
||||
|
||||
#include <tuple>
|
||||
#include <array>
|
||||
|
||||
static_assert(std::is_same<decltype(std::tuple_cat()),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<std::tuple<>>())),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<std::tuple<>&>())),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<const std::tuple<>>())),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<const std::tuple<>&>())),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<std::pair<int, bool>>())),
|
||||
std::tuple<int, bool>>::value, "Error");
|
||||
static_assert(std::is_same<decltype(std::tuple_cat
|
||||
(std::declval<std::pair<int, bool>&>())),
|
||||
std::tuple<int, bool>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<const std::pair<int, bool>>())),
|
||||
std::tuple<int, bool>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<const std::pair<int, bool>&>())),
|
||||
std::tuple<int, bool>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<std::array<int, 3>>())),
|
||||
std::tuple<int, int, int>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<std::array<int, 3>&>())),
|
||||
std::tuple<int, int, int>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<const std::array<int, 3>>())),
|
||||
std::tuple<int, int, int>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(std::declval<const std::array<int, 3>&>())),
|
||||
std::tuple<int, int, int>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::tuple<>>(), std::declval<std::tuple<>>())),
|
||||
std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::tuple<>>(), std::declval<std::tuple<>>(),
|
||||
std::declval<std::tuple<>>())), std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::tuple<>>(),
|
||||
std::declval<std::array<char, 0>>(),
|
||||
std::declval<std::array<int, 0>>(),
|
||||
std::declval<std::tuple<>>())), std::tuple<>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::tuple<int>>(),
|
||||
std::declval<std::tuple<double>>())),
|
||||
std::tuple<int, double>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::tuple<int>>(),
|
||||
std::declval<std::tuple<double>>(),
|
||||
std::declval<std::tuple<const long&>>())),
|
||||
std::tuple<int, double, const long&>>::value, "Error");
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat
|
||||
(std::declval<std::array<wchar_t, 3>&>(),
|
||||
std::declval<std::tuple<double>>(),
|
||||
std::declval<std::tuple<>>(),
|
||||
std::declval<std::tuple<unsigned&>>(),
|
||||
std::declval<std::pair<bool, std::nullptr_t>>())),
|
||||
std::tuple<wchar_t, wchar_t, wchar_t,
|
||||
double, unsigned&, bool, std::nullptr_t>
|
||||
>::value, "Error");
|
||||
|
||||
int main()
|
||||
{
|
||||
std::tuple_cat();
|
||||
std::tuple_cat(std::tuple<>{ });
|
||||
std::tuple_cat(std::tuple<>{ }, std::tuple<>{ });
|
||||
std::array<int, 3> a3;
|
||||
std::tuple_cat(a3);
|
||||
std::pair<double, bool> pdb;
|
||||
std::tuple<unsigned, float, std::nullptr_t, void*> t;
|
||||
int i{ };
|
||||
double d{ };
|
||||
int* pi{ };
|
||||
std::tuple<int&, double&, int*&> to{i, d, pi};
|
||||
std::tuple_cat(pdb);
|
||||
std::tuple_cat(to);
|
||||
std::tuple_cat(to, to);
|
||||
std::tuple_cat(a3, pdb);
|
||||
std::tuple_cat(a3, pdb, t);
|
||||
std::tuple_cat(a3, pdb, t, a3);
|
||||
std::tuple_cat(a3, pdb, t, a3, pdb, t);
|
||||
|
||||
static_assert(std::is_same<decltype
|
||||
(std::tuple_cat(a3, pdb, t, a3, pdb, t)),
|
||||
std::tuple<int, int, int, double, bool,
|
||||
unsigned, float, std::nullptr_t, void*,
|
||||
int, int, int, double, bool, unsigned,
|
||||
float, std::nullptr_t, void*>
|
||||
>::value, "Error");
|
||||
|
||||
std::tuple_cat(std::tuple<int, char, void*>{}, to, a3,
|
||||
std::tuple<>{}, std::pair<float,
|
||||
std::nullptr_t>{}, pdb, to);
|
||||
}
|
Loading…
Reference in New Issue
Block a user