// { dg-options "-std=gnu++11" }
// { dg-do compile }
// Copyright (C) 2012-2014 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
// .
#include
#include
#include
// TODO: Uncomment the following define once gcc has fixed bug 52748
// (incomplete types in function call expressions):
//#define HAS_52748_FIXED
// Helper types:
struct has_type_impl
{
template
static std::true_type test(int);
template
static std::false_type test(...);
};
template
struct has_type : public decltype(has_type_impl::test(0))
{};
template
struct is_expected_type : public std::is_same
{};
template
struct and_ : public std::conditional::type
{};
template
struct is_type : public and_, is_expected_type>
{};
// Types under inspection:
typedef bool (&PF1)();
typedef short (*PF2)(long);
struct S {
operator PF2() const;
double operator()(char, int&);
void calc(long) const;
};
typedef void (S::*PMS)(long) const;
typedef void (S::*PMSnonconst)(long);
typedef int S::* PMI;
struct B {
int i;
void f1() const;
bool f2(int) const volatile;
};
struct D : B {};
typedef void (B::*base_func_void)() const;
typedef bool (B::*base_func_bool_int)(int) const volatile;
struct ident_functor {
template
T operator()(T&& x);
};
template
struct variable_functor {
template
Ret operator()(T&&...);
};
struct ident_functor_noref {
template
typename std::remove_reference::type operator()(T&& x);
};
enum class ScEn;
enum UnScEn : int;
union U {
int i;
double d;
};
union U2 {
int i;
bool b;
void operator()() const;
int operator()(double) const;
bool operator()(double);
U operator()(int, int);
};
struct Ukn;
typedef Ukn (S::*PMSIncomplete)(long) const;
typedef Ukn (S::*PMSIncompletenonconst)(long);
typedef Ukn (*FuncIncomplete)(long);
struct Abstract {
virtual ~Abstract() = 0;
};
struct Private {
private:
void operator()();
int operator()(int);
public:
bool operator()(std::nullptr_t);
};
union PrivateUnion {
double d;
private:
void operator()();
int operator()(int);
public:
bool operator()(std::nullptr_t);
};
template
struct ImplicitTo {
operator T();
};
template
struct never { static const bool value = false; };
template
struct BrokenTrait {
static_assert(never::value, "Error!");
typedef T type;
};
template
struct BadSmartPtr : T {
T& operator*() const noexcept(typename BrokenTrait::type());
};
template
using FuncEllipses = Ret(...);
static_assert(is_type, short>::value, "Error!");
static_assert(is_type,
double>::value, "Error!");
static_assert(is_type, bool>::value, "Error!");
static_assert(is_type, bool>::value, "Error!");
static_assert(is_type, int)>,
void>::value, "Error!");
static_assert(is_type&, unsigned&)>,
void>::value, "Error!");
static_assert(is_type, int)>,
void>::value, "Error!");
static_assert(is_type&, unsigned&)>,
void>::value, "Error!");
static_assert(is_type,
int>::value, "Error!");
static_assert(is_type,
int>::value, "Error!");
static_assert(is_type,
int>::value, "Error!");
static_assert(is_type,
int>::value, "Error!");
static_assert(is_type,
int&>::value, "Error!");
static_assert(is_type,
B>::value, "Error!");
static_assert(is_type,
const B>::value, "Error!");
static_assert(is_type, B>::value, "Error!");
static_assert(is_type, B&>::value, "Error!");
static_assert(is_type, int&>::value, "Error!");
// This is expected as of CWG 616 P/R:
static_assert(is_type, int&&>::value, "Error!");
static_assert(is_type,
const volatile int&&>::value, "Error!");
static_assert(is_type,
const volatile int&&>::value, "Error!");
static_assert(is_type,
const int&>::value, "Error!");
static_assert(is_type,
const volatile int&>::value, "Error!");
static_assert(is_type,
const volatile int&>::value, "Error!");
static_assert(is_type, int&>::value, "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type,
const int&>::value, "Error!");
static_assert(is_type,
const int&>::value, "Error!");
static_assert(is_type,
const volatile int&>::value, "Error!");
static_assert(is_type,
const volatile int&>::value, "Error!");
static_assert(is_type,
void>::value, "Error!");
static_assert(is_type,
void>::value, "Error!");
static_assert(is_type,
void>::value, "Error!");
static_assert(is_type,
void>::value, "Error!");
static_assert(!has_type>::value,
"Error!");
static_assert(!has_type>::value,
"Error!");
static_assert(is_type,
bool>::value, "Error!");
static_assert(is_type,
bool>::value, "Error!");
static_assert(is_type,
bool>::value, "Error!");
static_assert(is_type,
bool>::value, "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, short>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, short>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, int)>, void>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type)>>(), "Error!");
// Argument number mismatch:
static_assert(!has_type)>>(), "Error!");
static_assert(!has_type&)>>(), "Error!");
static_assert(!has_type, int, bool)>>(),
"Error!");
static_assert(!has_type&, int, bool)>>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
// Non-convertible arguments:
static_assert(!has_type, S)>>(),
"Error!");
static_assert(!has_type&, S)>>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
// cv-violations:
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type, int&&>(), "Error!");
static_assert(is_type, int&&>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, int&&>(), "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type, const int&>(),
"Error!");
static_assert(is_type, const volatile int&>(), "Error!");
static_assert(is_type, const volatile int&>(), "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type, int&&>(), "Error!");
static_assert(is_type, const int&>(),
"Error!");
static_assert(is_type, const int&>(),
"Error!");
static_assert(is_type, const int&&>(),
"Error!");
typedef void (Ukn::* PUfnMF)();
typedef void (Ukn::* PUfnConstMF)() const;
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(),
"Error!");
static_assert(is_type, void>(),
"Error!");
static_assert(is_type, void>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, bool>(), "Error!");
static_assert(is_type, int>(), "Error!");
static_assert(is_type, bool>(), "Error!");
static_assert(is_type, bool>(), "Error!");
static_assert(is_type, bool>(), "Error!");
static_assert(is_type, int>(), "Error!");
static_assert(is_type, U>(), "Error!");
static_assert(is_type, U>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(is_type, int>(), "Error!");
static_assert(is_type,
int>(), "Error!");
static_assert(is_type, int&>(), "Error!");
static_assert(is_type,
const volatile int&>(), "Error!");
static_assert(is_type, int>(), "Error!");
static_assert(is_type,
int>(), "Error!");
static_assert(is_type, Abstract&>(),
"Error!");
static_assert(is_type,
const volatile Abstract&>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
// Border-line case:
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
// We want to allow this, it seems to be required by the order described
// in [func.require] p1:
static_assert(is_type&)>, int&>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type)>,
bool>(), "Error!");
static_assert(is_type)>,
bool>(), "Error!");
static_assert(is_type)>,
bool>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type)>>(), "Error!");
static_assert(!has_type)>>(),
"Error!");
static_assert(!has_type)>>(),
"Error!");
static_assert(!has_type)>>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type, bool>(),
"Error!");
static_assert(is_type)>,
bool>(), "Error!");
static_assert(is_type)>, bool>(), "Error!");
static_assert(is_type)>, bool>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type>(),
"Error!");
static_assert(!has_type)>>(),
"Error!");
static_assert(!has_type)>>(),
"Error!");
static_assert(!has_type)>>(), "Error!");
static_assert(!has_type)>>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type, void>(), "Error!");
static_assert(is_type))(int)>, void>(),
"Error!");
static_assert(is_type&))(int)>, void>(),
"Error!");
static_assert(is_type&&))(int)>, void>(),
"Error!");
static_assert(!has_type>(), "Error!");
static_assert(!has_type&))(int)>>(), "Error!");
static_assert(!has_type&&))(int)>>(), "Error!");
static_assert(is_type()>, void>(),
"Error!");
static_assert(is_type()>, void>(),
"Error!");
static_assert(!has_type(int)>>(),
"Error!");
static_assert(!has_type()>>(),
"Error!");
static_assert(!has_type(int)>>(),
"Error!");
static_assert(!has_type()>>(),
"Error!");
// Conversion operators of types are not considered in call expressions
// (except for conversion to function pointer/reference):
static_assert(!has_type(char, int&)>>(), "Error!");
static_assert(!has_type(int)>>(),
"Error!");
static_assert(is_type()>, void>(), "Error!");
static_assert(is_type(int)>, void>(),
"Error!");
static_assert(is_type(int, int)>, void>(),
"Error!");
static_assert(is_type(int, int, int)>,
void>(), "Error!");
static_assert(is_type&()>, void>(), "Error!");
static_assert(is_type