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

Jonathan Wakely jwakely@redhat.com
Wed Mar 15 22:31:00 GMT 2017


On 16/03/17 00:21 +0200, Ville Voutilainen wrote:
>Tested on Linux-x64.
>
>2017-03-16  Ville Voutilainen  <ville.voutilainen@gmail.com>
>
>    Implement LWG 2857, {variant,optional,any}::emplace should
>    return the constructed value.
>    * include/std/any (any_cast(any*)): Forward-declare.
>    (emplace(_Args&&...)): Change the return type and
>    return a reference to the constructed value.
>    (emplace(initializer_list<_Up>, _Args&&...)): Likewise.
>    * include/std/optional (emplace(_Args&&...)): Likewise.
>    (emplace(initializer_list<_Up>, _Args&&...)): Likewise.
>    * include/std/variant (emplace<_Tp>(_Args&&...)): Likewise.
>    (emplace<_Tp>(initializer_list<_Up>, _Args&&...)): Likewise.
>    (emplace<_Np>(_Args&&...)): Likewise.
>    (emplace<_Np>(initializer_list<_Up>, _Args&&...)): Likewise.
>    * testsuite/20_util/any/assign/emplace.cc: Add tests for
>    checking the return value of emplace.
>    * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
>    * testsuite/20_util/optional/assignment/6.cc: Add tests for
>    checking the return value of emplace.
>    * testsuite/20_util/variant/run.cc: Likewise.

>diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
>index e807617..fff13d9 100644
>--- a/libstdc++-v3/include/std/any
>+++ b/libstdc++-v3/include/std/any
>@@ -74,6 +74,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    *  An @c any object's state is either empty or it stores a contained object
>    *  of CopyConstructible type.
>    */
>+  class any;
>+  template<typename _ValueType>
>+    inline _ValueType* any_cast(any* __any) noexcept;
>+
>   class any
>   {
>     // Holds either pointer to a heap object or the contained object itself.
>@@ -268,18 +272,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>     /// Emplace with an object created from @p __args as the contained object.
>     template <typename _ValueType, typename... _Args>
>-      typename __any_constructible<void,
>+      typename __any_constructible<_Decay<_ValueType>&,
> 				   _Decay<_ValueType>, _Args&&...>::type
>       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.



More information about the Libstdc++ mailing list