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.
This commit is contained in:
Akim Demaille
2018-10-20 14:25:45 +02:00
parent 42f0b949ec
commit 3ead69b1c1
2 changed files with 24 additions and 7 deletions

View File

@@ -125,6 +125,18 @@ m4_define([b4_variant_define],
return *new (yyas_<T> ()) T (); return *new (yyas_<T> ()) T ();
} }
# if defined __cplusplus && 201103L <= __cplusplus
/// Instantiate a \a T in here from \a t.
template <typename T, typename U>
T&
emplace (U&& u)
{]b4_parse_assert_if([
YYASSERT (!yytypeid_);
YYASSERT (sizeof (T) <= S);
yytypeid_ = & typeid (T);])[
return *new (yyas_<T> ()) T (std::forward <U>(u));
}
# else
/// Instantiate a \a T in here from \a t. /// Instantiate a \a T in here from \a t.
template <typename T> template <typename T>
T& T&
@@ -135,6 +147,7 @@ m4_define([b4_variant_define],
yytypeid_ = & typeid (T);])[ yytypeid_ = & typeid (T);])[
return *new (yyas_<T> ()) T (t); return *new (yyas_<T> ()) T (t);
} }
# endif
/// Instantiate an empty \a T in here. /// Instantiate an empty \a T in here.
/// Obsolete, use emplace. /// Obsolete, use emplace.
@@ -200,10 +213,10 @@ m4_define([b4_variant_define],
void void
move (self_type& other) move (self_type& other)
{ {
emplace<T> ();
# if defined __cplusplus && 201103L <= __cplusplus # if defined __cplusplus && 201103L <= __cplusplus
as<T> () = std::move (other.as<T> ()); emplace<T> (std::move (other.as<T> ()));
# else # else
emplace<T> ();
swap<T> (other); swap<T> (other);
# endif # endif
other.destroy<T> (); other.destroy<T> ();
@@ -215,8 +228,7 @@ m4_define([b4_variant_define],
void void
move (self_type&& other) move (self_type&& other)
{ {
emplace<T> (); emplace<T> (std::move (other.as<T> ()));
as<T> () = std::move (other.as<T> ());
other.destroy<T> (); other.destroy<T> ();
} }
#endif #endif

View File

@@ -10836,12 +10836,17 @@ in midrule actions. It is mandatory to use typed midrule actions
(@pxref{Typed Midrule Actions}). (@pxref{Typed Midrule Actions}).
@deftypemethod {semantic_type} {T&} emplace<T> () @deftypemethod {semantic_type} {T&} emplace<T> ()
Initialize, but leave empty. Returns the address where the actual value may Initialize, but leave empty. Return a reference to where the actual value
be stored. Requires that the variant was not initialized yet. may be stored. Requires that the variant was not initialized yet.
@end deftypemethod @end deftypemethod
@deftypemethod {semantic_type} {T&} emplace<T> (const T& @var{t}) @deftypemethod {semantic_type} {T&} emplace<T> (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<T, U> (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 @end deftypemethod