[v3] Implement LWG 2857, {variant,optional,any}::emplace should return the constructed value.

Submitted by ville on March 15, 2017, 10:43 p.m.

Details

Message ID CAFk2RUZ+MGp69Thr=vVeJn-aqRMHKzG7OfwmT393nK3iwONbuw@mail.gmail.com
State New
Headers show

Commit Message

ville March 15, 2017, 10:43 p.m.
On 16 March 2017 at 00:31, Jonathan Wakely <jwakely@redhat.com> wrote:
>>       emplace(_Args&&... __args)
>>       {
>>         __do_emplace<_Decay<_ValueType>>
>>           (std::forward<_Args>(__args)...);
>> +       return *(std::any_cast<_Decay<_ValueType>>(this));
>
>
> Can we avoid the branch in any_cast to check the stored type?
> We know it's the right type, because we just stored it.

While I would hope the compiler to be smart enough to realize some of
that (we are passing in
this), the other branches might not be so easy. But certainly, we can
axe every one of the extraneous
branches, like in the attached amendment.

Comments

Jonathan Wakely March 15, 2017, 11:05 p.m.
On 16/03/17 00:43 +0200, Ville Voutilainen wrote:
>On 16 March 2017 at 00:31, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>       emplace(_Args&&... __args)
>>>       {
>>>         __do_emplace<_Decay<_ValueType>>
>>>           (std::forward<_Args>(__args)...);
>>> +       return *(std::any_cast<_Decay<_ValueType>>(this));
>>
>>
>> Can we avoid the branch in any_cast to check the stored type?
>> We know it's the right type, because we just stored it.
>
>While I would hope the compiler to be smart enough to realize some of
>that (we are passing in
>this), the other branches might not be so easy. But certainly, we can
>axe every one of the extraneous
>branches, like in the attached amendment.

And then we don't need the forward declarations of any and any_ast,
right?

OK for trunk like that, thanks.

Patch hide | download patch | download mbox

diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index fff13d9..ef6efa5 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -278,7 +278,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	__do_emplace<_Decay<_ValueType>>
 	  (std::forward<_Args>(__args)...);
-	return *(std::any_cast<_Decay<_ValueType>>(this));
+	any::_Arg __arg;
+	this->_M_manager(any::_Op_access, this, &__arg);
+	return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
       }
 
     /// Emplace with an object created from @p __il and @p __args as
@@ -292,7 +294,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	__do_emplace<_Decay<_ValueType>, _Up>
 	  (__il, std::forward<_Args>(__args)...);
-	return *(std::any_cast<_Decay<_ValueType>>(this));
+	any::_Arg __arg;
+	this->_M_manager(any::_Op_access, this, &__arg);
+	return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
       }
 
     // modifiers
diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
index 2d2b3d3..8e3ca73 100644
--- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
@@ -26,5 +26,5 @@  void test01()
   using std::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 461 }
+  any_cast<int&>(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 465 }
 }