bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Support emplace with multiple arguments


From: Akim Demaille
Subject: Re: Support emplace with multiple arguments
Date: Mon, 10 Dec 2018 17:53:37 +0100

Hi Askar,

> Le 8 déc. 2018 à 20:56, Askar Safin <address@hidden> a écrit :
> 
> Hi. It seems that you wanted your "build" function of "variant.hh" to be 
> named idiomatically, and so created new "emplace" function. Well, okey, but 
> if you really want to be idiomatic, please, make it support multiple 
> arguments. I. e. it should look so:
> 
>    template <typename T, typename... U>
>    T&
>    emplace (U&&... u)
>    {
>      return *new (yyas_<T> ()) T (std::forward <U>(u), ...);
>    }
> 
> Of course, this will cover empty argument list case, too, so, if this 
> definition is enabled, then you don't need "emplace ()".

Ok, I did it as bellow.  But do you actually use this?  Don't you use 
api.token.constructor instead?  I had not done that, because I don't
think users should use this API.  It existed before symbol ctors,
that I consider superior.

commit 951c88c1d471346f220233ea8839ec42a188062f
Author: Akim Demaille <address@hidden>
Date:   Mon Dec 10 17:41:24 2018 +0100

    C++: support variadic emplace
    
    Suggested by Askar Safin.
    http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00006.html
    
    * data/variant.hh: Implement.
    * tests/types.at: Check.
    * doc/bison.texi: Document.

diff --git a/NEWS b/NEWS
index 3b714d6a..75db0f17 100644
--- a/NEWS
+++ b/NEWS
@@ -100,6 +100,22 @@ GNU Bison NEWS
   until it sees the '='.  So we notate the two possible reductions to
   indicate that each conflicts in one rule.
 
+*** C++: Variadic emplace
+
+  If your application requires C++11, you may now use a variadic value type
+  constructor:
+
+    %define api.value.type variant
+    %token <std::pair<int, int>> PAIR
+
+  in your scanner:
+
+    int yylex (parser::semantic_type *lvalp)
+    {
+      lvalp->emplace <std::pair<int, int>> (1, 2);
+      return parser::token::PAIR;
+    }
+
 *** More POSIX Yacc compatibility warnings
 
   More Bison specific directives are now reported with -y or -Wyacc.  This
diff --git a/data/variant.hh b/data/variant.hh
index 3264528a..47ff9cbd 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -121,29 +121,29 @@ m4_define([b4_value_type_declare],
       YYASSERT (!yytypeid_);
     ])[}
 
-    /// Instantiate an empty \a T in here.
-    template <typename T>
+# if 201103L <= YY_CPLUSPLUS
+    /// Instantiate a \a T in here from \a t.
+    template <typename T, typename... U>
     T&
-    emplace ()
+    emplace (U&&... u)
     {]b4_parse_assert_if([
       YYASSERT (!yytypeid_);
       YYASSERT (sizeof (T) <= size);
       yytypeid_ = & typeid (T);])[
-      return *new (yyas_<T> ()) T ();
+      return *new (yyas_<T> ()) T (std::forward <U>(u)...);
     }
-
-# if 201103L <= YY_CPLUSPLUS
-    /// Instantiate a \a T in here from \a t.
-    template <typename T, typename U>
+# else
+    /// Instantiate an empty \a T in here.
+    template <typename T>
     T&
-    emplace (U&& u)
+    emplace ()
     {]b4_parse_assert_if([
       YYASSERT (!yytypeid_);
       YYASSERT (sizeof (T) <= size);
       yytypeid_ = & typeid (T);])[
-      return *new (yyas_<T> ()) T (std::forward <U>(u));
+      return *new (yyas_<T> ()) T ();
     }
-# else
+
     /// Instantiate a \a T in here from \a t.
     template <typename T>
     T&
diff --git a/doc/bison.texi b/doc/bison.texi
index 8a66236d..e20ae028 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -11088,20 +11088,17 @@ in midrule actions.  It is mandatory to use typed 
midrule actions
 (@pxref{Typed Midrule Actions}).
 
 @deftypemethod {semantic_type} {T&} emplace<T> ()
-Initialize, but leave empty.  Return a reference to where the actual value
-may be stored.  Requires that the variant was not initialized yet.
address@hidden {semantic_type} {T&} emplace<T> (const T& @var{t})
+Available in C++98/C++03 only.  Default construct/copy-construct from
address@hidden  Return a reference to where the actual value may be stored.
+Requires that the variant was not initialized yet.
 @end deftypemethod
 
address@hidden {semantic_type} {T&} emplace<T> (const T& @var{t})
-Initialize, and copy-construct from @var{t}.  Available in C++98/C++03 only.
address@hidden {semantic_type} {T&} emplace<T, U> (U&&... @var{u})
+Available in C++11 and later only.  Build a variant of type @code{T} from
+the variadic forwarding references @var{u...}.
 @end deftypemethod
 
address@hidden {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.
address@hidden deftypemethod
-
-
 @strong{Warning}: We do not use Boost.Variant, for two reasons.  First, it
 appeared unacceptable to require Boost on the user's machine (i.e., the
 machine on which the generated parser will be compiled, not the machine on
diff --git a/tests/types.at b/tests/types.at
index a2758917..1bbb958d 100644
--- a/tests/types.at
+++ b/tests/types.at
@@ -288,21 +288,22 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], 
[glr.cc]],
                AT_VAL.build (std::make_pair<std::string, std::string> ("two", 
"deux"));],
             [10:11, two:deux])
 
-    # Move-only types.
+    # Move-only types, and variadic emplace.
     AT_TEST([%skeleton "]b4_skel["
              %code requires { #include <memory> }
              %define api.value.type variant],
             [[%token <std::unique_ptr<int>> '1';
-             %token <std::unique_ptr<std::string>> '2';]],
-            ['1' '2' { std::cout << *$1 << ", " << *$2 << '\n'; }],
+             %token <std::pair<int, int>> '2';]],
+            ['1' '2' { std::cout << *$1 << ", "
+                                 << $2.first << ", "
+                                 << $2.second << '\n'; }],
             ["12"],
             [[if (res == '1')
                ]AT_VAL[.emplace <std::unique_ptr<int>>
                  (std::make_unique <int> (10));
              else if (res == '2')
-               ]AT_VAL[.emplace <std::unique_ptr<std::string>>
-                 (std::make_unique <std::string> ("two"));]],
-            [10, two],
+               ]AT_VAL[.emplace <std::pair<int, int>> (21, 22);]],
+            [10, 21, 22],
             [AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; 
continue])])])
   ])
 ])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]