type_traits (common_time): Provide "SFINAE-friendly" implementation.
2012-10-09 Daniel Krugler <daniel.kruegler@googlemail.com> * include/std/type_traits (common_time): Provide "SFINAE-friendly" implementation. (__success_type, __failure_type): Fix. * include/std/chrono (common_type): Likewise for the chrono::time_point specialization. * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc: New. * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc: Likewise. * testsuite/20_util/duration/requirements/sfinae_friendly_1.cc: Likewise. * testsuite/20_util/common_type/requirements/typedefs-1.cc: Adjust wrt LWG 2141. * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust dg-error line numbers. * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Likewise. * testsuite/20_util/duration/requirements/typedefs_neg3.cc: Likewise. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. * testsuite/20_util/result_of/sfinae_friendly_1.cc: Trivial stylistic tweaks. * testsuite/20_util/result_of/sfinae_friendly_2.cc: Likewise. From-SVN: r192276
This commit is contained in:
parent
71111e6b20
commit
b3618b7167
15 changed files with 632 additions and 73 deletions
|
@ -1,3 +1,30 @@
|
|||
2012-10-09 Daniel Krugler <daniel.kruegler@googlemail.com>
|
||||
|
||||
* include/std/type_traits (common_time): Provide "SFINAE-friendly"
|
||||
implementation.
|
||||
(__success_type, __failure_type): Fix.
|
||||
* include/std/chrono (common_type): Likewise for the chrono::time_point
|
||||
specialization.
|
||||
* testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc: New.
|
||||
* testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc:
|
||||
Likewise.
|
||||
* testsuite/20_util/duration/requirements/sfinae_friendly_1.cc:
|
||||
Likewise.
|
||||
* testsuite/20_util/common_type/requirements/typedefs-1.cc: Adjust wrt
|
||||
LWG 2141.
|
||||
* testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust
|
||||
dg-error line numbers.
|
||||
* testsuite/20_util/duration/requirements/typedefs_neg2.cc: Likewise.
|
||||
* testsuite/20_util/duration/requirements/typedefs_neg3.cc: Likewise.
|
||||
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise.
|
||||
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
|
||||
Likewise.
|
||||
* testsuite/20_util/declval/requirements/1_neg.cc: Likewise.
|
||||
|
||||
* testsuite/20_util/result_of/sfinae_friendly_1.cc: Trivial stylistic
|
||||
tweaks.
|
||||
* testsuite/20_util/result_of/sfinae_friendly_2.cc: Likewise.
|
||||
|
||||
2012-10-09 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR libstdc++/54861
|
||||
|
|
|
@ -69,33 +69,53 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
|||
}
|
||||
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// 20.11.4.3 specialization of common_type (for duration)
|
||||
|
||||
// 20.11.4.3 specialization of common_type (for duration, sfinae-friendly)
|
||||
|
||||
template<typename _CT, typename _Period1, typename _Period2>
|
||||
struct __duration_common_type_wrapper
|
||||
{
|
||||
private:
|
||||
typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num;
|
||||
typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den;
|
||||
typedef typename _CT::type __cr;
|
||||
typedef ratio<__gcd_num::value,
|
||||
(_Period1::den / __gcd_den::value) * _Period2::den> __r;
|
||||
public:
|
||||
typedef __success_type<chrono::duration<__cr, __r>> type;
|
||||
};
|
||||
|
||||
template<typename _Period1, typename _Period2>
|
||||
struct __duration_common_type_wrapper<__failure_type, _Period1, _Period2>
|
||||
{ typedef __failure_type type; };
|
||||
|
||||
template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
|
||||
struct common_type<chrono::duration<_Rep1, _Period1>,
|
||||
chrono::duration<_Rep2, _Period2>>
|
||||
{
|
||||
private:
|
||||
typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num;
|
||||
typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den;
|
||||
typedef typename common_type<_Rep1, _Rep2>::type __cr;
|
||||
typedef ratio<__gcd_num::value,
|
||||
(_Period1::den / __gcd_den::value) * _Period2::den> __r;
|
||||
chrono::duration<_Rep2, _Period2>>
|
||||
: public __duration_common_type_wrapper<typename __member_type_wrapper<
|
||||
common_type<_Rep1, _Rep2>>::type, _Period1, _Period2>::type
|
||||
{ };
|
||||
|
||||
public:
|
||||
typedef chrono::duration<__cr, __r> type;
|
||||
// 20.11.4.3 specialization of common_type (for time_point, sfinae-friendly)
|
||||
|
||||
template<typename _CT, typename _Clock>
|
||||
struct __timepoint_common_type_wrapper
|
||||
{
|
||||
typedef __success_type<chrono::time_point<_Clock, typename _CT::type>>
|
||||
type;
|
||||
};
|
||||
|
||||
// 20.11.4.3 specialization of common_type (for time_point)
|
||||
template<typename _Clock, typename _Dur1, typename _Dur2>
|
||||
struct common_type<chrono::time_point<_Clock, _Dur1>,
|
||||
chrono::time_point<_Clock, _Dur2>>
|
||||
{
|
||||
private:
|
||||
typedef typename common_type<_Dur1, _Dur2>::type __ct;
|
||||
template<typename _Clock>
|
||||
struct __timepoint_common_type_wrapper<__failure_type, _Clock>
|
||||
{ typedef __failure_type type; };
|
||||
|
||||
template<typename _Clock, typename _Duration1, typename _Duration2>
|
||||
struct common_type<chrono::time_point<_Clock, _Duration1>,
|
||||
chrono::time_point<_Clock, _Duration2>>
|
||||
: public __timepoint_common_type_wrapper<typename __member_type_wrapper<
|
||||
common_type<_Duration1, _Duration2>>::type, _Clock>::type
|
||||
{ };
|
||||
|
||||
public:
|
||||
typedef chrono::time_point<_Clock, __ct> type;
|
||||
};
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
|
||||
namespace chrono
|
||||
|
|
|
@ -133,6 +133,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
typedef struct { char __arr[2]; } __two;
|
||||
};
|
||||
|
||||
// For several sfinae-friendly trait implementations we transport both the
|
||||
// result information (as the member type) and the failure information (no
|
||||
// member type). This is very similar to std::enable_if, but we cannot use
|
||||
// them, because we need to derive from them as an implementation detail.
|
||||
|
||||
template<typename _Tp>
|
||||
struct __success_type
|
||||
{ typedef _Tp type; };
|
||||
|
||||
struct __failure_type
|
||||
{ };
|
||||
|
||||
// primary type categories.
|
||||
|
||||
template<typename>
|
||||
|
@ -1771,25 +1783,70 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
struct conditional<false, _Iftrue, _Iffalse>
|
||||
{ typedef _Iffalse type; };
|
||||
|
||||
|
||||
/// common_type
|
||||
template<typename... _Tp>
|
||||
struct common_type;
|
||||
|
||||
// sfinae-friendly common_type implementation:
|
||||
|
||||
struct __do_common_type_impl
|
||||
{
|
||||
template<typename _Tp, typename _Up>
|
||||
static __success_type<typename decay<
|
||||
decltype(true ? std::declval<_Tp>() : std::declval<_Up>())
|
||||
>::type> _S_test(int);
|
||||
|
||||
template<typename, typename>
|
||||
static __failure_type _S_test(...);
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Up>
|
||||
struct __common_type_impl
|
||||
: private __do_common_type_impl
|
||||
{
|
||||
typedef decltype(_S_test<_Tp, _Up>(0)) type;
|
||||
};
|
||||
|
||||
struct __do_member_type_wrapper
|
||||
{
|
||||
template<typename _Tp>
|
||||
static __success_type<typename _Tp::type> _S_test(int);
|
||||
|
||||
template<typename>
|
||||
static __failure_type _S_test(...);
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __member_type_wrapper
|
||||
: private __do_member_type_wrapper
|
||||
{
|
||||
typedef decltype(_S_test<_Tp>(0)) type;
|
||||
};
|
||||
|
||||
template<typename _CTp, typename... _Args>
|
||||
struct __expanded_common_type_wrapper
|
||||
{
|
||||
typedef common_type<typename _CTp::type, _Args...> type;
|
||||
};
|
||||
|
||||
template<typename... _Args>
|
||||
struct __expanded_common_type_wrapper<__failure_type, _Args...>
|
||||
{ typedef __failure_type type; };
|
||||
|
||||
template<typename _Tp>
|
||||
struct common_type<_Tp>
|
||||
{ typedef _Tp type; };
|
||||
|
||||
template<typename _Tp, typename _Up>
|
||||
struct common_type<_Tp, _Up>
|
||||
{ typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
|
||||
: public __common_type_impl<_Tp, _Up>::type
|
||||
{ };
|
||||
|
||||
template<typename _Tp, typename _Up, typename... _Vp>
|
||||
struct common_type<_Tp, _Up, _Vp...>
|
||||
{
|
||||
typedef typename
|
||||
common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
|
||||
};
|
||||
: public __expanded_common_type_wrapper<typename __member_type_wrapper<
|
||||
common_type<_Tp, _Up>>::type, _Vp...>::type
|
||||
{ };
|
||||
|
||||
/// The underlying type of an enum.
|
||||
template<typename _Tp>
|
||||
|
@ -1818,14 +1875,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
template<typename _Signature>
|
||||
class result_of;
|
||||
|
||||
// sfinae-friendly result_of implementation. We use enable_if to transport
|
||||
// both the result information (as the member type) and the failure
|
||||
// information (no member type).
|
||||
|
||||
template<typename _Tp>
|
||||
using __success_type = enable_if<true, _Tp>;
|
||||
|
||||
using __failure_type = enable_if<false>;
|
||||
// sfinae-friendly result_of implementation:
|
||||
|
||||
// [func.require] paragraph 1 bullet 1:
|
||||
struct __result_of_memfun_ref_impl
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
// { dg-options "-std=c++11" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2012 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/>.
|
||||
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
|
||||
//TODO: Uncomment this once gcc bug 53000 has been resolved:
|
||||
//#define HAS_53000_FIXED
|
||||
|
||||
// Helper types:
|
||||
struct has_type_impl
|
||||
{
|
||||
template<typename T, typename = typename T::type>
|
||||
static std::true_type test(int);
|
||||
template<typename>
|
||||
static std::false_type test(...);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct has_type : public decltype(has_type_impl::test<T>(0))
|
||||
{};
|
||||
|
||||
template<typename T, typename Expected>
|
||||
struct is_expected_type : public std::is_same<typename T::type, Expected>
|
||||
{};
|
||||
|
||||
template<typename P1, typename P2>
|
||||
struct and_ : public std::conditional<P1::value, P2, std::false_type>::type
|
||||
{};
|
||||
|
||||
template<typename T, typename Expected>
|
||||
struct is_type : public and_<has_type<T>, is_expected_type<T, Expected>>
|
||||
{};
|
||||
|
||||
// Inspection types:
|
||||
|
||||
struct S {};
|
||||
|
||||
struct B {};
|
||||
struct D : B {};
|
||||
|
||||
struct F1 { operator void*(); };
|
||||
struct F2 { operator void*(); };
|
||||
|
||||
struct G1 { operator const void*(); };
|
||||
struct G2 { operator volatile void*(); };
|
||||
|
||||
template<typename T>
|
||||
struct ImplicitTo
|
||||
{
|
||||
operator T();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ExplicitTo
|
||||
{
|
||||
explicit operator T();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct PrivateImplicitTo
|
||||
{
|
||||
private:
|
||||
operator T();
|
||||
};
|
||||
|
||||
auto lmd1 = [](int, double) {};
|
||||
auto lmd2 = [](int, double) {};
|
||||
|
||||
struct Abstract
|
||||
{
|
||||
virtual ~Abstract() = 0;
|
||||
};
|
||||
|
||||
enum class ScEn;
|
||||
|
||||
enum UnscEn : int;
|
||||
|
||||
struct Ukn;
|
||||
|
||||
union U
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
union U2
|
||||
{
|
||||
long i;
|
||||
};
|
||||
|
||||
union UConv1
|
||||
{
|
||||
operator Abstract*();
|
||||
};
|
||||
|
||||
union UConv2
|
||||
{
|
||||
operator Abstract*();
|
||||
};
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct RX12 {};
|
||||
struct RX21 {};
|
||||
struct Y1 {};
|
||||
struct Y2 {};
|
||||
struct Y3 {};
|
||||
struct Y4 {};
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct common_type<X1, X2>
|
||||
{
|
||||
typedef RX12 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct common_type<X2, X1>
|
||||
{
|
||||
typedef RX21 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct common_type<RX12, X1>
|
||||
{
|
||||
typedef Y1 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct common_type<X1, RX12>
|
||||
{
|
||||
typedef Y2 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct common_type<RX21, X1>
|
||||
{
|
||||
typedef Y3 type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct common_type<X1, RX21>
|
||||
{
|
||||
typedef Y4 type;
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(is_type<std::common_type<int, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<ScEn, ScEn>, ScEn>(), "");
|
||||
static_assert(is_type<std::common_type<UnscEn, UnscEn>, UnscEn>(), "");
|
||||
static_assert(is_type<std::common_type<int, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<UnscEn, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<int, int, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<int, int, int, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<int, int, int, int, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<S, S>, S>(), "");
|
||||
static_assert(is_type<std::common_type<const S, const S>, S>(), "");
|
||||
static_assert(is_type<std::common_type<std::initializer_list<int>,
|
||||
std::initializer_list<int>>, std::initializer_list<int>>(), "");
|
||||
static_assert(is_type<std::common_type<B, D>, B>(), "");
|
||||
static_assert(is_type<std::common_type<D, B>, B>(), "");
|
||||
static_assert(is_type<std::common_type<F1, F2>, void*>(), "");
|
||||
static_assert(is_type<std::common_type<F2, F1>, void*>(), "");
|
||||
static_assert(is_type<std::common_type<G1, G2>, const volatile void*>(), "");
|
||||
static_assert(is_type<std::common_type<G2, G1>, const volatile void*>(), "");
|
||||
static_assert(is_type<std::common_type<int*, const volatile int*>,
|
||||
const volatile int*>(), "");
|
||||
static_assert(is_type<std::common_type<void*, const volatile int*>,
|
||||
const volatile void*>(), "");
|
||||
static_assert(is_type<std::common_type<void, void>, void>(), "");
|
||||
static_assert(is_type<std::common_type<const void, const void>, void>(), "");
|
||||
static_assert(is_type<std::common_type<int&, int&&>, int>(), "");
|
||||
static_assert(is_type<std::common_type<int&, int&>, int>(), "");
|
||||
static_assert(is_type<std::common_type<int&&, int&&>, int>(), "");
|
||||
static_assert(is_type<std::common_type<U&, const U&&>, U>(), "");
|
||||
static_assert(is_type<std::common_type<U&, U&>, U>(), "");
|
||||
static_assert(is_type<std::common_type<U&&, U&&>, U>(), "");
|
||||
static_assert(is_type<std::common_type<int B::*, int D::*>, int D::*>(), "");
|
||||
static_assert(is_type<std::common_type<int D::*, int B::*>, int D::*>(), "");
|
||||
static_assert(is_type<std::common_type<const int B::*, volatile int D::*>,
|
||||
const volatile int D::*>(), "");
|
||||
static_assert(is_type<std::common_type<int (B::*)(), int (D::*)()>,
|
||||
int (D::*)()>(), "");
|
||||
static_assert(is_type<std::common_type<int (B::*)() const, int (D::*)() const>,
|
||||
int (D::*)() const>(), "");
|
||||
static_assert(is_type<std::common_type<int[3], int[3]>, int*>(), "");
|
||||
static_assert(is_type<std::common_type<int[1], const int[3]>,
|
||||
const int*>(), "");
|
||||
static_assert(is_type<std::common_type<void(), void()>, void(*)()>(), "");
|
||||
static_assert(is_type<std::common_type<void(&)(), void(&)()>, void(*)()>(), "");
|
||||
static_assert(is_type<std::common_type<void(&)(), void(&&)()>,
|
||||
void(*)()>(), "");
|
||||
static_assert(is_type<std::common_type<void(&&)(), void(&)()>,
|
||||
void(*)()>(), "");
|
||||
static_assert(is_type<std::common_type<void(&&)(), void(&&)()>,
|
||||
void(*)()>(), "");
|
||||
static_assert(is_type<std::common_type<ImplicitTo<int>, int>, int>(), "");
|
||||
static_assert(is_type<std::common_type<ImplicitTo<int>, ImplicitTo<int>>,
|
||||
ImplicitTo<int>>(), "");
|
||||
static_assert(is_type<std::common_type<ImplicitTo<int>, int,
|
||||
ImplicitTo<int>>, int>(), "");
|
||||
static_assert(is_type<std::common_type<ExplicitTo<int>, ExplicitTo<int>>,
|
||||
ExplicitTo<int>>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(lmd1), decltype(lmd1)>,
|
||||
decltype(lmd1)>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd1)&>,
|
||||
decltype(lmd1)>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(lmd1)&, decltype(lmd2)&>,
|
||||
void(*)(int, double)>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), void*>, void*>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), int*>, int*>(), "");
|
||||
static_assert(is_type<std::common_type<const decltype(nullptr)&, int*>,
|
||||
int*>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), const volatile int*>,
|
||||
const volatile int*>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), int (B::*)()>,
|
||||
int (B::*)()>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), int (B::*)() const>,
|
||||
int (B::*)() const>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(nullptr), const int B::*>,
|
||||
const int B::*>(), "");
|
||||
static_assert(is_type<std::common_type<Abstract&, Abstract&>, Abstract>(), "");
|
||||
static_assert(is_type<std::common_type<Ukn&, Ukn&>, Ukn>(), "");
|
||||
static_assert(is_type<std::common_type<ImplicitTo<B&>, B&>, B>(), "");
|
||||
static_assert(is_type<std::common_type<ImplicitTo<B&>&, B&&>, B>(), "");
|
||||
static_assert(is_type<std::common_type<UConv1, const Abstract*&>,
|
||||
const Abstract*>(), "");
|
||||
static_assert(is_type<std::common_type<UConv1, UConv2>, Abstract*>(), "");
|
||||
static_assert(is_type<std::common_type<UConv1&, UConv2&>, Abstract*>(), "");
|
||||
|
||||
#ifdef HAS_53000_FIXED
|
||||
static_assert(is_type<std::common_type<Abstract&&, Abstract&&>,
|
||||
Abstract>(), "");
|
||||
static_assert(is_type<std::common_type<const Abstract&&,
|
||||
volatile Abstract&&>, Abstract>(), "");
|
||||
static_assert(is_type<std::common_type<Ukn&&, Ukn&&>, Ukn>(), "");
|
||||
static_assert(is_type<std::common_type<const Ukn&&, volatile Ukn&&>,
|
||||
Ukn>(), "");
|
||||
#endif
|
||||
|
||||
static_assert(is_type<std::common_type<X1, X2>, RX12>(), "");
|
||||
static_assert(is_type<std::common_type<X2, X1>, RX21>(), "");
|
||||
|
||||
static_assert(is_type<std::common_type<X1, X2, X1>, Y1>(), "");
|
||||
static_assert(is_type<std::common_type<X2, X1, X1>, Y3>(), "");
|
||||
|
||||
static_assert(is_type<std::common_type<X1, X1, X2>, RX12>(), "");
|
||||
static_assert(is_type<std::common_type<X1, X1, X2, X1>, Y1>(), "");
|
||||
|
||||
static_assert(!has_type<std::common_type<>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<U, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<U, U2>>(), "");
|
||||
static_assert(!has_type<std::common_type<const ImplicitTo<int>, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<PrivateImplicitTo<int>, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<const PrivateImplicitTo<int>,
|
||||
int>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, Ukn>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, Abstract>>(), "");
|
||||
static_assert(!has_type<std::common_type<Ukn, Abstract>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, const volatile void>>(), "");
|
||||
static_assert(!has_type<std::common_type<Abstract, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<Ukn, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<int[4], void>>(), "");
|
||||
static_assert(!has_type<std::common_type<ScEn, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<UnscEn, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<U, void>>(), "");
|
||||
static_assert(!has_type<std::common_type<std::initializer_list<int>,
|
||||
void>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, int, int, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, int, S, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, S, int, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<S, int, int, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, int, void, int, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<B, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, B, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<B, int, S>>(), "");
|
||||
static_assert(!has_type<std::common_type<B, S, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<int*, double*>>(), "");
|
||||
static_assert(!has_type<std::common_type<void*, void(*)(...)>>(), "");
|
||||
static_assert(!has_type<std::common_type<void(*)(), void(*)(...)>>(), "");
|
||||
static_assert(!has_type<std::common_type<void(*)(), void(S::*)()>>(), "");
|
||||
static_assert(!has_type<std::common_type<void(S::*)() const,
|
||||
void(S::*)()>>(), "");
|
||||
static_assert(!has_type<std::common_type<int S::*, long S::*>>(), "");
|
||||
static_assert(!has_type<std::common_type<int S::*, void(S::*)()>>(), "");
|
||||
static_assert(!has_type<std::common_type<int (B::*)(),
|
||||
int (D::*)() const>>(), "");
|
||||
static_assert(!has_type<std::common_type<int (B::*)() const,
|
||||
int (D::*)()>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, ExplicitTo<int>>>(), "");
|
||||
static_assert(!has_type<std::common_type<ImplicitTo<int>,
|
||||
ExplicitTo<int>>>(), "");
|
||||
static_assert(!has_type<std::common_type<ScEn, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<ScEn, UnscEn>>(), "");
|
||||
static_assert(!has_type<std::common_type<U, S, Abstract, void, D,
|
||||
int (B::*)(), int[5]>>(), "");
|
||||
static_assert(!has_type<std::common_type<UConv1, Abstract&&>>(), "");
|
||||
static_assert(!has_type<std::common_type<std::initializer_list<int>,
|
||||
std::initializer_list<long>>>(), "");
|
||||
|
||||
void test(int i)
|
||||
{
|
||||
auto local_lmd1 = [=](int, double) { return i + i; };
|
||||
auto local_lmd2 = [=](int, double) { return i - i; };
|
||||
|
||||
static_assert(is_type<std::common_type<decltype(local_lmd1),
|
||||
decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
|
||||
decltype(local_lmd1)>, decltype(local_lmd1)>(), "");
|
||||
static_assert(is_type<std::common_type<decltype(local_lmd1)&,
|
||||
decltype(local_lmd1)&>, decltype(local_lmd1)>(), "");
|
||||
|
||||
static_assert(!has_type<std::common_type<decltype(local_lmd1),
|
||||
decltype(lmd1)>>(), "");
|
||||
static_assert(!has_type<std::common_type<decltype(local_lmd1)&,
|
||||
decltype(lmd1)&>>(), "");
|
||||
static_assert(!has_type<std::common_type<decltype(local_lmd1),
|
||||
decltype(local_lmd2)>>(), "");
|
||||
static_assert(!has_type<std::common_type<decltype(local_lmd1)&,
|
||||
decltype(local_lmd2)&>>(), "");
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// { dg-options "-std=c++11" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2012 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/>.
|
||||
|
||||
#include <type_traits>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
template<typename... Args>
|
||||
constexpr
|
||||
std::array<typename std::common_type<Args...>::type, sizeof...(Args)>
|
||||
make_array(Args&&... args) // { dg-error "invalid use" }
|
||||
{
|
||||
typedef typename std::common_type<Args...>::type CT;
|
||||
return std::array<CT, sizeof...(Args)>{static_cast<CT>
|
||||
(std::forward<Args>(args))...};
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
constexpr auto a1 = make_array(0);
|
||||
constexpr auto a2 = make_array(0, 1.2);
|
||||
constexpr auto a3 = make_array(5, true, 3.1415f, 'c');
|
||||
|
||||
static_assert(std::is_same<decltype(a1), const std::array<int, 1>>(), "");
|
||||
static_assert(std::is_same<decltype(a2), const std::array<double, 2>>(), "");
|
||||
static_assert(std::is_same<decltype(a3), const std::array<float, 4>>(), "");
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
make_array(); // { dg-error "no matching function" }
|
||||
}
|
||||
// { dg-prune-output "substitution" }
|
||||
// { dg-prune-output "include" }
|
|
@ -1,6 +1,6 @@
|
|||
// { dg-options "-std=gnu++0x" }
|
||||
//
|
||||
// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008-2012 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
|
||||
|
@ -105,7 +105,7 @@ void test02()
|
|||
COMMON_TYPE_TEST_ALL_2(int, int, int, 1);
|
||||
COMMON_TYPE_TEST_ALL_2(int, double, double, 2);
|
||||
COMMON_TYPE_TEST_2(NO_CV, A, A, A, 3);
|
||||
COMMON_TYPE_TEST_2(const, A, A, const A, 4);
|
||||
COMMON_TYPE_TEST_2(const, A, A, A, 4);
|
||||
COMMON_TYPE_TEST_2(NO_CV, B, A, A, 5);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *-*-* } 1812 }
|
||||
// { dg-error "static assertion failed" "" { target *-*-* } 1869 }
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
// { dg-options "-std=c++11" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2012 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/>.
|
||||
|
||||
#include <type_traits>
|
||||
#include <chrono>
|
||||
|
||||
// Helper types:
|
||||
struct has_type_impl
|
||||
{
|
||||
template<typename T, typename = typename T::type>
|
||||
static std::true_type test(int);
|
||||
template<typename>
|
||||
static std::false_type test(...);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct has_type : public decltype(has_type_impl::test<T>(0))
|
||||
{};
|
||||
|
||||
template<typename T, typename Expected>
|
||||
struct is_expected_type : public std::is_same<typename T::type, Expected>
|
||||
{};
|
||||
|
||||
template<typename P1, typename P2>
|
||||
struct and_ : public std::conditional<P1::value, P2, std::false_type>::type
|
||||
{};
|
||||
|
||||
template<typename T, typename Expected>
|
||||
struct is_type : public and_<has_type<T>, is_expected_type<T, Expected>>
|
||||
{};
|
||||
|
||||
// Inspection types:
|
||||
|
||||
typedef std::chrono::duration<int, std::nano> din;
|
||||
typedef std::chrono::duration<double, std::nano> ddn;
|
||||
typedef std::chrono::duration<int, std::milli> dim;
|
||||
|
||||
static_assert(is_type<std::common_type<din, din>, din>(), "");
|
||||
static_assert(is_type<std::common_type<din, din, din>, din>(), "");
|
||||
|
||||
static_assert(is_type<std::common_type<din, ddn>, ddn>(), "");
|
||||
static_assert(is_type<std::common_type<din, din, ddn>, ddn>(), "");
|
||||
static_assert(is_type<std::common_type<din, ddn>, ddn>(), "");
|
||||
static_assert(is_type<std::common_type<ddn, din, din>, ddn>(), "");
|
||||
|
||||
static_assert(!has_type<std::common_type<din, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<din, din, int>>(), "");
|
||||
static_assert(!has_type<std::common_type<int, din, din>>(), "");
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// { dg-require-cstdint "" }
|
||||
// 2008-07-31 Chris Fairles <chris.fairles@gmail.com>
|
||||
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008-2012 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
|
||||
|
@ -31,5 +31,5 @@ void test01()
|
|||
test_type d;
|
||||
}
|
||||
|
||||
// { dg-error "rep cannot be a duration" "" { target *-*-* } 225 }
|
||||
// { dg-error "rep cannot be a duration" "" { target *-*-* } 245 }
|
||||
// { dg-error "required from here" "" { target *-*-* } 31 }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// { dg-require-cstdint "" }
|
||||
// 2008-07-31 Chris Fairles <chris.fairles@gmail.com>
|
||||
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008-2012 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
|
||||
|
@ -32,5 +32,5 @@ void test01()
|
|||
test_type d; // { dg-error "required from here" }
|
||||
}
|
||||
|
||||
// { dg-error "must be a specialization of ratio" "" { target *-*-* } 226 }
|
||||
// { dg-error "must be a specialization of ratio" "" { target *-*-* } 246 }
|
||||
// { dg-prune-output "not a member" }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// { dg-require-cstdint "" }
|
||||
// 2008-07-31 Chris Fairles <chris.fairles@gmail.com>
|
||||
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008-2012 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
|
||||
|
@ -33,5 +33,5 @@ void test01()
|
|||
test_type d;
|
||||
}
|
||||
|
||||
// { dg-error "period must be positive" "" { target *-*-* } 228 }
|
||||
// { dg-error "period must be positive" "" { target *-*-* } 248 }
|
||||
// { dg-error "required from here" "" { target *-*-* } 33 }
|
||||
|
|
|
@ -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 *-*-* } 1601 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1565 }
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1613 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1577 }
|
||||
|
|
|
@ -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 *-*-* } 1519 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1483 }
|
||||
// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1531 }
|
||||
// { dg-error "declaration of" "" { target *-*-* } 1495 }
|
||||
|
|
|
@ -29,23 +29,27 @@
|
|||
// Helper types:
|
||||
struct has_type_impl
|
||||
{
|
||||
template<class T, class = typename T::type>
|
||||
template<typename T, typename = typename T::type>
|
||||
static std::true_type test(int);
|
||||
|
||||
template<class>
|
||||
template<typename>
|
||||
static std::false_type test(...);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct has_type : decltype(has_type_impl::test<T>(0))
|
||||
template<typename T>
|
||||
struct has_type : public decltype(has_type_impl::test<T>(0))
|
||||
{};
|
||||
|
||||
template<class T, class Res>
|
||||
struct is_expected_type : std::is_same<typename T::type, Res>
|
||||
template<typename T, typename Res>
|
||||
struct is_expected_type : public std::is_same<typename T::type, Res>
|
||||
{};
|
||||
|
||||
template<class T, class Res>
|
||||
struct is_type : std::__and_<has_type<T>, is_expected_type<T, Res>>
|
||||
template<typename P1, typename P2>
|
||||
struct and_ : public std::conditional<P1::value, P2, std::false_type>::type
|
||||
{};
|
||||
|
||||
template<typename T, typename Res>
|
||||
struct is_type : public and_<has_type<T>, is_expected_type<T, Res>>
|
||||
{};
|
||||
|
||||
// Types under inspection:
|
||||
|
@ -76,18 +80,18 @@ typedef void (B::*base_func_void)() const;
|
|||
typedef bool (B::*base_func_bool_int)(int) const volatile;
|
||||
|
||||
struct ident_functor {
|
||||
template<class T>
|
||||
template<typename T>
|
||||
T operator()(T&& x);
|
||||
};
|
||||
|
||||
template<class Ret = void>
|
||||
template<typename Ret = void>
|
||||
struct variable_functor {
|
||||
template<class... T>
|
||||
template<typename... T>
|
||||
Ret operator()(T&&...);
|
||||
};
|
||||
|
||||
struct ident_functor_noref {
|
||||
template<class T>
|
||||
template<typename T>
|
||||
typename std::remove_reference<T>::type operator()(T&& x);
|
||||
};
|
||||
|
||||
|
@ -136,26 +140,26 @@ public:
|
|||
bool operator()(std::nullptr_t);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template<typename T>
|
||||
struct ImplicitTo {
|
||||
operator T();
|
||||
};
|
||||
|
||||
template<class>
|
||||
template<typename>
|
||||
struct never { static const bool value = false; };
|
||||
|
||||
template<class T>
|
||||
template<typename T>
|
||||
struct BrokenTrait {
|
||||
static_assert(never<T>::value, "Error!");
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template<typename T>
|
||||
struct BadSmartPtr : T {
|
||||
T& operator*() const noexcept(typename BrokenTrait<T>::type());
|
||||
};
|
||||
|
||||
template<class Ret>
|
||||
template<typename Ret>
|
||||
using FuncEllipses = Ret(...);
|
||||
|
||||
static_assert(is_type<std::result_of<S(int)>, short>::value, "Error!");
|
||||
|
|
|
@ -23,16 +23,16 @@
|
|||
#include <type_traits>
|
||||
#include <string>
|
||||
|
||||
struct eat { template<class T> eat(T const &) {} };
|
||||
struct eat { template<typename T> eat(T const &) {} };
|
||||
struct not_incrementable {};
|
||||
|
||||
struct inc {
|
||||
template<class T>
|
||||
template<typename T>
|
||||
auto operator()(T t) const -> decltype(t++)
|
||||
{ return t++; }
|
||||
};
|
||||
|
||||
template<class A>
|
||||
template<typename A>
|
||||
typename std::result_of<inc(A)>::type // sfinae here
|
||||
try_inc(A a) {
|
||||
return inc()(a);
|
||||
|
@ -43,10 +43,10 @@ try_inc(eat) {
|
|||
return not_incrementable();
|
||||
}
|
||||
|
||||
template<class>
|
||||
template<typename>
|
||||
struct never { static const bool value = false; };
|
||||
|
||||
template<class T>
|
||||
template<typename T>
|
||||
struct Fail
|
||||
{
|
||||
static_assert(never<T>::value, "duh");
|
||||
|
@ -55,16 +55,16 @@ struct Fail
|
|||
|
||||
struct Fun
|
||||
{
|
||||
template<class T>
|
||||
template<typename T>
|
||||
typename Fail<T>::type operator()(T)
|
||||
{ return 0; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template<typename T>
|
||||
typename std::result_of<Fun(T)>::type foo(T)
|
||||
{ return 0; }
|
||||
|
||||
template<class>
|
||||
template<typename>
|
||||
int foo(...)
|
||||
{ return 0; }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue