// { dg-options "-std=gnu++0x" } // { dg-do compile } // 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 // . #include #include struct S { }; struct S0 { typedef int argument_type; }; struct S1 { typedef float first_argument_type; }; struct S2 { typedef char second_argument_type; }; struct S01 : S0, S1 { }; struct S02 : S0, S2 { }; struct S12 : S1, S2 { }; struct S012 : S0, S1, S2 { }; using std::__sfinae_types; using std::integral_constant; using std::remove_cv; _GLIBCXX_HAS_NESTED_TYPE(argument_type) _GLIBCXX_HAS_NESTED_TYPE(first_argument_type) _GLIBCXX_HAS_NESTED_TYPE(second_argument_type) template struct has_arg_type : __has_argument_type { }; template struct has_1st_arg_type : __has_first_argument_type { }; template struct has_2nd_arg_type : __has_second_argument_type { }; template::value> struct test_arg_type { static_assert( !has_arg_type>::value, "reference_wrapper has no nested argument_type"); }; template struct test_arg_type { typedef std::reference_wrapper ref; static_assert( has_arg_type::value, "reference_wrapper has nested argument_type"); static_assert( std::is_same< typename T::argument_type, typename ref::argument_type >::value, "reference_wrapper has the correct argument_type"); }; template::value && has_2nd_arg_type::value> struct test_1st_2nd_arg_types { typedef std::reference_wrapper ref; static_assert( !has_1st_arg_type::value, "reference_wrapper has no nested first_argument_type"); static_assert( !has_2nd_arg_type::value, "reference_wrapper has no nested second_argument_type"); }; template struct test_1st_2nd_arg_types { typedef std::reference_wrapper ref; static_assert( has_1st_arg_type::value, "reference_wrapper has nested first_argument_type"); static_assert( has_2nd_arg_type::value, "reference_wrapper has nested second_argument_type"); static_assert( std::is_same< typename T::first_argument_type, typename ref::first_argument_type>::value, "reference_wrapper has correct first_argument_type"); static_assert( std::is_same< typename T::second_argument_type, typename ref::second_argument_type>::value, "reference_wrapper has correct second_argument_type"); }; template void test() { test_arg_type t; test_arg_type tc; test_arg_type tv; test_arg_type tcv; test_1st_2nd_arg_types t12; test_1st_2nd_arg_types t12c; test_1st_2nd_arg_types t12v; test_1st_2nd_arg_types t12cv; } int main() { test(); test(); test(); test(); test(); test(); test(); test(); }