From 3ead69b1c1241100b7a2d2b6c6fd89d545c23ca4 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 20 Oct 2018 14:25:45 +0200 Subject: [PATCH] c++: prefer a perfect forwarding version of variant's emplace * data/variant.hh (emplace): In modern C++, use only a perfect forwarding version. And use it. * doc/bison.texi: Document it. --- data/variant.hh | 20 ++++++++++++++++---- doc/bison.texi | 11 ++++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/data/variant.hh b/data/variant.hh index 089e04fa..5cc3df11 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -125,6 +125,18 @@ m4_define([b4_variant_define], return *new (yyas_ ()) T (); } +# if defined __cplusplus && 201103L <= __cplusplus + /// Instantiate a \a T in here from \a t. + template + T& + emplace (U&& u) + {]b4_parse_assert_if([ + YYASSERT (!yytypeid_); + YYASSERT (sizeof (T) <= S); + yytypeid_ = & typeid (T);])[ + return *new (yyas_ ()) T (std::forward (u)); + } +# else /// Instantiate a \a T in here from \a t. template T& @@ -135,6 +147,7 @@ m4_define([b4_variant_define], yytypeid_ = & typeid (T);])[ return *new (yyas_ ()) T (t); } +# endif /// Instantiate an empty \a T in here. /// Obsolete, use emplace. @@ -200,10 +213,10 @@ m4_define([b4_variant_define], void move (self_type& other) { - emplace (); # if defined __cplusplus && 201103L <= __cplusplus - as () = std::move (other.as ()); + emplace (std::move (other.as ())); # else + emplace (); swap (other); # endif other.destroy (); @@ -215,8 +228,7 @@ m4_define([b4_variant_define], void move (self_type&& other) { - emplace (); - as () = std::move (other.as ()); + emplace (std::move (other.as ())); other.destroy (); } #endif diff --git a/doc/bison.texi b/doc/bison.texi index fcee42fe..00c59a37 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -10836,12 +10836,17 @@ in midrule actions. It is mandatory to use typed midrule actions (@pxref{Typed Midrule Actions}). @deftypemethod {semantic_type} {T&} emplace () -Initialize, but leave empty. Returns the address where the actual value may -be stored. Requires that the variant was not initialized yet. +Initialize, but leave empty. Return a reference to where the actual value +may be stored. Requires that the variant was not initialized yet. @end deftypemethod @deftypemethod {semantic_type} {T&} emplace (const T& @var{t}) -Initialize, and copy-construct from @var{t}. +Initialize, and copy-construct from @var{t}. Available in C++98/C++03 only. +@end deftypemethod + +@deftypemethod {semantic_type} {T&} emplace (U&& @var{u}) +Build a variant of type @code{T} from the forwarding reference @var{u}. +Available in C++11 and later only. @end deftypemethod