mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2011-09-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
* include/std/tuple: Use everywhere std::size_t... instead of int...
|
* include/std/tuple: Use everywhere std::size_t... instead of int...
|
||||||
|
|
|
||||||
|
|
@ -443,11 +443,10 @@ particular release.
|
||||||
<entry/>
|
<entry/>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<?dbhtml bgcolor="#B0B0B0" ?>
|
|
||||||
<entry>20.4.2.4</entry>
|
<entry>20.4.2.4</entry>
|
||||||
<entry>Tuple creation functions</entry>
|
<entry>Tuple creation functions</entry>
|
||||||
<entry>Partial</entry>
|
<entry>Y</entry>
|
||||||
<entry><code>tuple_cat</code> should be a single variadic signature (DR 1385)</entry>
|
<entry/>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>20.4.2.5</entry>
|
<entry>20.4.2.5</entry>
|
||||||
|
|
|
||||||
|
|
@ -876,108 +876,184 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
forward_as_tuple(_Elements&&... __args) noexcept
|
forward_as_tuple(_Elements&&... __args) noexcept
|
||||||
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
|
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
|
||||||
|
|
||||||
template<std::size_t...> struct __index_holder { };
|
|
||||||
|
|
||||||
template<std::size_t __i, typename _IdxHolder, typename... _Elements>
|
template<typename, std::size_t> struct array;
|
||||||
struct __index_holder_impl;
|
|
||||||
|
|
||||||
template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
|
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||||
typename... _Elements>
|
_Tp& get(array<_Tp, _Nm>&) noexcept;
|
||||||
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>
|
||||||
|
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,
|
typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
|
||||||
__index_holder<_Indexes..., __i>,
|
|
||||||
_Elements...>::type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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>
|
// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
|
||||||
struct __make_index_holder
|
template<std::size_t _Num>
|
||||||
: __index_holder_impl<0, __index_holder<>, _Elements...> { };
|
struct _Build_index_tuple
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return __tuple_cat_helper(__t, typename
|
typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type;
|
||||||
__make_index_holder<_TElements...>::type(),
|
};
|
||||||
__u, typename
|
|
||||||
__make_index_holder<_UElements...>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... _TElements, typename... _UElements>
|
template<>
|
||||||
inline tuple<_TElements..., _UElements...>
|
struct _Build_index_tuple<0>
|
||||||
tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
|
|
||||||
{
|
{
|
||||||
return __tuple_cat_helper(std::move(__t), typename
|
typedef _Index_tuple<> __type;
|
||||||
__make_index_holder<_TElements...>::type(),
|
};
|
||||||
__u, typename
|
|
||||||
__make_index_holder<_UElements...>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... _TElements, typename... _UElements>
|
template<std::size_t, typename, typename, std::size_t>
|
||||||
inline tuple<_TElements..., _UElements...>
|
struct __make_tuple_impl;
|
||||||
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<typename... _TElements, typename... _UElements>
|
template<std::size_t _Idx, typename _Tuple, typename... _Tp,
|
||||||
inline tuple<_TElements..., _UElements...>
|
std::size_t _Nm>
|
||||||
tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
|
struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
|
||||||
{
|
{
|
||||||
return __tuple_cat_helper(std::move(__t), typename
|
typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
|
||||||
__make_index_holder<_TElements...>::type(),
|
typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
|
||||||
std::move(__u), typename
|
__type;
|
||||||
__make_index_holder<_UElements...>::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>
|
template<typename... _Elements>
|
||||||
|
|
@ -1007,29 +1083,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Types, typename _Alloc>
|
template<typename... _Types, typename _Alloc>
|
||||||
struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
|
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...
|
// See stl_pair.h...
|
||||||
template<class _T1, class _T2>
|
template<class _T1, class _T2>
|
||||||
template<typename _Tp, typename... _Args>
|
template<typename _Tp, typename... _Args>
|
||||||
|
|
|
||||||
|
|
@ -45,23 +45,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
* @addtogroup metaprogramming
|
* @addtogroup metaprogramming
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
struct __sfinae_types
|
|
||||||
{
|
/// integral_constant
|
||||||
typedef char __one;
|
template<typename _Tp, _Tp __v>
|
||||||
typedef struct { char __arr[2]; } __two;
|
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.
|
// Meta programming helper types.
|
||||||
|
|
||||||
template<bool, typename, typename>
|
template<bool, typename, typename>
|
||||||
struct conditional;
|
struct conditional;
|
||||||
|
|
||||||
template<typename _Tp, _Tp>
|
|
||||||
struct integral_constant;
|
|
||||||
|
|
||||||
template<typename...>
|
template<typename...>
|
||||||
struct __or_;
|
struct __or_;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct __or_<>
|
||||||
|
: public false_type
|
||||||
|
{ };
|
||||||
|
|
||||||
template<typename _B1>
|
template<typename _B1>
|
||||||
struct __or_<_B1>
|
struct __or_<_B1>
|
||||||
: public _B1
|
: public _B1
|
||||||
|
|
@ -80,6 +96,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename...>
|
template<typename...>
|
||||||
struct __and_;
|
struct __and_;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct __and_<>
|
||||||
|
: public true_type
|
||||||
|
{ };
|
||||||
|
|
||||||
template<typename _B1>
|
template<typename _B1>
|
||||||
struct __and_<_B1>
|
struct __and_<_B1>
|
||||||
: public _B1
|
: public _B1
|
||||||
|
|
@ -100,26 +121,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
: public integral_constant<bool, !_Pp::value>
|
: public integral_constant<bool, !_Pp::value>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// helper class.
|
struct __sfinae_types
|
||||||
|
{
|
||||||
/// integral_constant
|
typedef char __one;
|
||||||
template<typename _Tp, _Tp __v>
|
typedef struct { char __arr[2]; } __two;
|
||||||
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;
|
|
||||||
|
|
||||||
// primary type categories.
|
// primary type categories.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
// with this library; see the file COPYING3. If not see
|
// with this library; see the file COPYING3. If not see
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// { dg-error "static assertion failed" "" { target *-*-* } 1725 }
|
// { dg-error "static assertion failed" "" { target *-*-* } 1731 }
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,5 +48,5 @@ void test01()
|
||||||
// { dg-error "required from here" "" { target *-*-* } 40 }
|
// { dg-error "required from here" "" { target *-*-* } 40 }
|
||||||
// { dg-error "required from here" "" { target *-*-* } 42 }
|
// { dg-error "required from here" "" { target *-*-* } 42 }
|
||||||
|
|
||||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1511 }
|
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1517 }
|
||||||
// { dg-error "declaration of" "" { target *-*-* } 1475 }
|
// { 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 *-*-* } 40 }
|
||||||
// { dg-error "required from here" "" { target *-*-* } 42 }
|
// { dg-error "required from here" "" { target *-*-* } 42 }
|
||||||
|
|
||||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1435 }
|
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1441 }
|
||||||
// { dg-error "declaration of" "" { target *-*-* } 1399 }
|
// { dg-error "declaration of" "" { target *-*-* } 1405 }
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ test_get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// tuple_cat
|
// tuple_cat
|
||||||
|
#if 0
|
||||||
void
|
void
|
||||||
test_tuple_cat()
|
test_tuple_cat()
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +74,7 @@ test_tuple_cat()
|
||||||
constexpr tuple_type2 t2 { 55, 99, 77.77 };
|
constexpr tuple_type2 t2 { 55, 99, 77.77 };
|
||||||
constexpr auto cat1 = std::tuple_cat(t1, t2);
|
constexpr auto cat1 = std::tuple_cat(t1, t2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
|
|
@ -84,7 +85,9 @@ main()
|
||||||
|
|
||||||
test_get();
|
test_get();
|
||||||
|
|
||||||
|
#if 0
|
||||||
test_tuple_cat();
|
test_tuple_cat();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
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