Commit b1c2b51b by Jonathan Wakely Committed by Jonathan Wakely

functional (_Mem_fn): Constrain function call operators to avoid ambiguities.

	* include/std/functional (_Mem_fn): Constrain function call operators
	to avoid ambiguities. Use perfect forwarding.
	* testsuite/20_util/function_objects/mem_fn/55463.cc: Additional
	tests.
	* testsuite/20_util/function_objects/mem_fn/forward.cc: New.
	* testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line numbers.

From-SVN: r193879
parent 69bccd4a
2012-11-28 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/std/functional (_Mem_fn): Constrain function call operators
to avoid ambiguities. Use perfect forwarding.
* testsuite/20_util/function_objects/mem_fn/55463.cc: Additional
tests.
* testsuite/20_util/function_objects/mem_fn/forward.cc: New.
* testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line numbers.
2012-11-27 Ollie Wild <aaw@google.com>
* include/bits/stl_tree.h (@headername): Fix incorrect Doxygen macro
......
......@@ -30,10 +30,10 @@ void test01()
{
const int dummy = 0;
std::bind(&inc, _1)(0); // { dg-error "no match" }
// { dg-error "rvalue|const" "" { target *-*-* } 1224 }
// { dg-error "rvalue|const" "" { target *-*-* } 1238 }
// { dg-error "rvalue|const" "" { target *-*-* } 1252 }
// { dg-error "rvalue|const" "" { target *-*-* } 1266 }
// { dg-error "rvalue|const" "" { target *-*-* } 1349 }
// { dg-error "rvalue|const" "" { target *-*-* } 1363 }
// { dg-error "rvalue|const" "" { target *-*-* } 1377 }
// { dg-error "rvalue|const" "" { target *-*-* } 1391 }
std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" }
}
......
......@@ -32,7 +32,12 @@ struct X
int data;
};
struct Y : X { };
using CX = const X;
using CY = const Y;
using X_ptr = X*;
struct smart_ptr
{
......@@ -41,38 +46,63 @@ struct smart_ptr
std::reference_wrapper<X> ref();
std::reference_wrapper<const X> cref();
std::reference_wrapper<Y> yref();
void test01()
{
int& i1 = std::mem_fn( &X::func )( X() );
int& i2 = std::mem_fn( &X::func )( smart_ptr() );
int& i2 = std::mem_fn( &X::func )( Y() );
int& i3 = std::mem_fn( &X::func )( ref() );
int& i4 = std::mem_fn( &X::func )( yref() );
int& i5 = std::mem_fn( &X::func )( X_ptr() );
int& i6 = std::mem_fn( &X::func )( smart_ptr() );
char& c1 = std::mem_fn( &X::func_c )( X() );
char& c2 = std::mem_fn( &X::func_c )( CX() );
char& c3 = std::mem_fn( &X::func_c )( smart_ptr() );
char& c3 = std::mem_fn( &X::func_c )( Y() );
char& c4 = std::mem_fn( &X::func_c )( ref() );
char& c5 = std::mem_fn( &X::func_c )( cref() );
char& c6 = std::mem_fn( &X::func_c )( yref() );
char& c7 = std::mem_fn( &X::func_c )( X_ptr() );
char& c8 = std::mem_fn( &X::func_c )( smart_ptr() );
short& s1 = std::mem_fn( &X::func_v )( X() );
short& s2 = std::mem_fn( &X::func_v )( smart_ptr() );
short& s2 = std::mem_fn( &X::func_v )( Y() );
short& s3 = std::mem_fn( &X::func_v )( ref() );
short& s4 = std::mem_fn( &X::func_v )( yref() );
short& s5 = std::mem_fn( &X::func_v )( X_ptr() );
short& s6 = std::mem_fn( &X::func_v )( smart_ptr() );
double& d1 = std::mem_fn( &X::func_cv )( X() );
double& d2 = std::mem_fn( &X::func_cv )( CX() );
double& d3 = std::mem_fn( &X::func_cv )( smart_ptr() );
double& d3 = std::mem_fn( &X::func_cv )( Y() );
double& d4 = std::mem_fn( &X::func_cv )( ref() );
double& d5 = std::mem_fn( &X::func_cv )( cref() );
double& d6 = std::mem_fn( &X::func_cv )( yref() );
double& d7 = std::mem_fn( &X::func_cv )( X_ptr() );
double& d8 = std::mem_fn( &X::func_cv )( smart_ptr() );
// [expr.mptr.oper]
// The result of a .* expression whose second operand is a pointer to a
// data member is of the same value category (3.10) as its first operand.
int&& rval = std::mem_fn( &X::data )( X() );
const int&& crval = std::mem_fn( &X::data )( CX() );
int& sval = std::mem_fn( &X::data )( smart_ptr() );
int&& yrval = std::mem_fn( &X::data )( Y() );
const int&& ycrval = std::mem_fn( &X::data )( CY() );
int& val = std::mem_fn( &X::data )( ref() );
const int& cval = std::mem_fn( &X::data )( cref() );
int& yval = std::mem_fn( &X::data )( yref() );
int& pval = std::mem_fn( &X::data )( X_ptr() );
int& sval = std::mem_fn( &X::data )( smart_ptr() );
}
void test02()
{
std::reference_wrapper<X> r = ref();
X& x1 = std::mem_fn( &std::reference_wrapper<X>::get )( r );
const std::reference_wrapper<X> cr = ref();
const X& x3 = std::mem_fn( &std::reference_wrapper<X>::get )( cr );
X& x2 = std::mem_fn( &std::reference_wrapper<X>::get )( ref() );
}
// { dg-options "-std=gnu++11" }
// 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 <functional>
#include <testsuite_hooks.h>
struct Counter
{
Counter() = default;
Counter(const Counter&) { ++count; }
static int count;
};
int Counter::count = 0;
struct X
{
int func(Counter, int i) { return i; }
char func_c(Counter, char c) const { return c; }
short func_v(Counter, short s) volatile { return s; }
double func_cv(Counter, double d) const volatile { return d; }
};
void test01()
{
Counter c;
X x;
std::mem_fn( &X::func )( x, c, 0 );
VERIFY( Counter::count == 1 );
std::mem_fn( &X::func_c )( x, c, 0 );
VERIFY( Counter::count == 2 );
std::mem_fn( &X::func_v )( x, c, 0 );
VERIFY( Counter::count == 3 );
std::mem_fn( &X::func_cv )( x, c, 0 );
VERIFY( Counter::count == 4 );
}
int main()
{
test01();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment