// { 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&(int)>, void>(), "Error!"); static_assert(is_type&(int, int)>, void>(), "Error!"); static_assert(is_type&(int, int, int)>, void>(), "Error!"); static_assert(!has_type()>>(), "Error!"); static_assert(!has_type(int)>>(), "Error!"); static_assert(!has_type(int, int)>>(), "Error!"); static_assert(!has_type(int, int, int)>>(), "Error!"); static_assert(!has_type&()>>(), "Error!"); static_assert(!has_type&(int)>>(), "Error!"); static_assert(!has_type&(int, int)>>(), "Error!"); static_assert(!has_type&(int, int, int)>>(), "Error!"); static_assert(is_type()>, S>(), "Error!"); static_assert(is_type(int)>, S>(), "Error!"); static_assert(is_type(int, int)>, S>(), "Error!"); static_assert(is_type(int, int, int)>, S>(), "Error!"); static_assert(is_type&()>, S>(), "Error!"); static_assert(is_type&(int)>, S>(), "Error!"); static_assert(is_type&(int, int)>, S>(), "Error!"); static_assert(is_type&(int, int, int)>, S>(), "Error!"); static_assert(!has_type()>>(), "Error!"); static_assert(!has_type(int)>>(), "Error!"); static_assert(!has_type(int, int)>>(), "Error!"); static_assert(!has_type(int, int, int)>>(), "Error!"); static_assert(!has_type&()>>(), "Error!"); static_assert(!has_type&(int)>>(), "Error!"); static_assert(!has_type&(int, int)>>(), "Error!"); static_assert(!has_type&(int, int, int)>>(), "Error!"); #if defined(HAS_52748_FIXED) static_assert(has_type()>>(), "Error!"); static_assert(is_type()>, Ukn>(), "Error!"); static_assert(is_type(int)>, Ukn>(), "Error!"); static_assert(is_type(int, int)>, Ukn>(), "Error!"); static_assert(is_type(int, int, int)>, Ukn>(), "Error!"); static_assert(is_type&()>, Ukn>(), "Error!"); static_assert(is_type&(int)>, Ukn>(), "Error!"); static_assert(is_type&(int, int)>, Ukn>(), "Error!"); static_assert(is_type&(int, int, int)>, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type, Ukn>(), "Error!"); static_assert(is_type*()>, Ukn>(), "Error!"); static_assert(is_type&()>, Ukn>(), "Error!"); static_assert(is_type&&()>, Ukn>(), "Error!"); static_assert(is_type*(bool)>, Ukn>(), "Error!"); static_assert(is_type&(bool)>, Ukn>(), "Error!"); static_assert(is_type&&(bool)>, Ukn>(), "Error!"); static_assert(is_type*(bool, int, S)>, Ukn>(), "Error!"); static_assert(is_type&(bool, int, S)>, Ukn>(), "Error!"); static_assert(is_type&&(bool, int, S)>, Ukn>(), "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!"); #endif static_assert(!has_type()>>(), "Error!"); static_assert(!has_type(int)>>(), "Error!"); static_assert(!has_type(int, int)>>(), "Error!"); static_assert(!has_type(int, int, int)>>(), "Error!"); static_assert(!has_type&()>>(), "Error!"); static_assert(!has_type&(int)>>(), "Error!"); static_assert(!has_type&(int, int)>>(), "Error!"); static_assert(!has_type&(int, int, 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(!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*(bool)>, int>(), "Error!"); static_assert(is_type&(bool)>, int>(), "Error!"); static_assert(is_type&&(bool)>, int>(), "Error!"); static_assert(is_type*(bool, int, S)>, int>(), "Error!"); static_assert(is_type&(bool, int, S)>, int>(), "Error!"); static_assert(is_type&&(bool, int, S)>, int>(), "Error!");