blob: 43c951a8e540243c24fbc0f5bd333e6f70faa1c3 [file] [log] [blame]
// { dg-options "-Wno-deprecated-declarations" }
// { dg-do compile { target c++11 } }
// Copyright (C) 2008-2023 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 <functional>
#include <type_traits>
namespace __gnu_test
{
template<typename T> using void_t = void;
struct none;
#if __cplusplus <= 201703L
// For C++11/14/17 if the nested type is not found, require
// that the test used 'none' as the expected type.
template<typename U> using not_found = std::is_same<U, none>;
// A nested type needs to match the expected type.
template<typename U, typename V> using found = std::is_same<U, V>;
#else
// For C++20 the nested type should always be not found.
template<typename U> using not_found = std::true_type;
// Any nested type is bad.
template<typename U, typename V> using found = std::false_type;
#endif
template<typename T, typename U, typename = void>
struct check_result_type
: not_found<U>
{ };
// Matches when reference_wrapper<T>::result_type exists
template<typename T, typename U>
struct check_result_type<T, U, void_t<typename std::reference_wrapper<T>::result_type>>
: found<U, typename std::reference_wrapper<T>::result_type>
{ };
template<typename T, typename U, typename = void>
struct check_arg_type
: not_found<U>
{ };
// Matches when reference_wrapper<T>::argument_type exists
template<typename T, typename U>
struct check_arg_type<T, U, void_t<typename std::reference_wrapper<T>::argument_type>>
: found<U, typename std::reference_wrapper<T>::argument_type>
{ };
template<typename T, typename U, typename = void>
struct check_first_arg_type
: not_found<U>
{ };
// Matches when reference_wrapper<T>::first_argument_type exists
template<typename T, typename U>
struct check_first_arg_type<T, U, void_t<typename std::reference_wrapper<T>::first_argument_type>>
: found<U, typename std::reference_wrapper<T>::first_argument_type>
{ };
template<typename T, typename U, typename = void>
struct check_second_arg_type
: not_found<U>
{ };
// Matches when reference_wrapper<T>::second_argument_type exists
template<typename T, typename U>
struct check_second_arg_type<T, U, void_t<typename std::reference_wrapper<T>::second_argument_type>>
: found<U, typename std::reference_wrapper<T>::second_argument_type>
{ };
} // namespace __gnu_test
struct X {};
struct int_result_type { typedef int result_type; };
struct derives_unary : std::unary_function<int, int> {};
struct derives_binary : std::binary_function<int, float, int> {};
struct derives_unary_binary
: std::unary_function<int, int>,
std::binary_function<int, float, int>
{
typedef int result_type;
};
void test01()
{
using std::is_same;
using __gnu_test::check_result_type;
using __gnu_test::none;
// Check result_type typedef
static_assert( check_result_type<int_result_type, int>::value, "has result_type" );
static_assert( check_result_type<derives_unary, int>::value, "has result_type" );
static_assert( check_result_type<derives_binary, int>::value, "has result_type" );
static_assert( check_result_type<derives_unary_binary, int>::value, "has result_type" );
static_assert( check_result_type<int(void), int>::value, "has result_type" );
static_assert( check_result_type<int(*)(void), int>::value, "has result_type" );
static_assert( check_result_type<int (::X::*)(), int>::value, "has result_type" );
static_assert( check_result_type<int (::X::*)(float), int>::value, "has result_type" );
}
void test02()
{
using __gnu_test::check_arg_type;
using __gnu_test::check_first_arg_type;
using __gnu_test::check_second_arg_type;
using __gnu_test::none;
// Check argument_type typedef
static_assert( check_arg_type<int_result_type, none>::value, "" );
static_assert( check_arg_type<derives_unary, int>::value, "" );
static_assert( check_arg_type<derives_binary, none>::value, "" );
static_assert( check_arg_type<derives_unary_binary, int>::value, "" );
static_assert( check_arg_type<int(void), none>::value, "" );
static_assert( check_arg_type<int(*)(void), none>::value, "" );
static_assert( check_arg_type<int (::X::*)(), X*>::value, "" );
static_assert( check_arg_type<int (::X::*)() const, const X*>::value, "" );
static_assert( check_arg_type<int (::X::*)(float), none>::value, "" );
static_assert( check_arg_type<int (::X::*)(char, char), none>::value, "" );
// Check first_argument_type typedef
static_assert( check_first_arg_type<int_result_type, none>::value, "" );
static_assert( check_first_arg_type<derives_unary, none>::value, "" );
static_assert( check_first_arg_type<derives_binary, int>::value, "" );
static_assert( check_first_arg_type<derives_unary_binary, int>::value, "" );
static_assert( check_first_arg_type<int(void), none>::value, "" );
static_assert( check_first_arg_type<int(*)(void), none>::value, "" );
static_assert( check_first_arg_type<int (::X::*)(), none>::value, "" );
static_assert( check_first_arg_type<int (::X::*)(float), X*>::value, "" );
static_assert( check_first_arg_type<int (::X::*)(float) const, const X*>::value, "" );
static_assert( check_first_arg_type<int (::X::*)(char, char), none>::value, "" );
// Check second_argument_type typedef
static_assert( check_second_arg_type<int_result_type, none>::value, "" );
static_assert( check_second_arg_type<derives_unary, none>::value, "" );
static_assert( check_second_arg_type<derives_binary, float>::value, "" );
static_assert( check_second_arg_type<derives_unary_binary, float>::value, "" );
static_assert( check_second_arg_type<int(void), none>::value, "" );
static_assert( check_second_arg_type<int(*)(void), none>::value, "" );
static_assert( check_second_arg_type<int (::X::*)(), none>::value, "" );
static_assert( check_second_arg_type<int (::X::*)(float), float>::value, "" );
static_assert( check_second_arg_type<int (::X::*)(float) const, float>::value, "" );
static_assert( check_second_arg_type<int (::X::*)(char, char), none>::value, "" );
}
int main()
{
test01();
}