bison-patches
[Top][All Lists]
Advanced

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

Re: RFC: lalr1.cc: support move semantics


From: Akim Demaille
Subject: Re: RFC: lalr1.cc: support move semantics
Date: Thu, 13 Sep 2018 06:51:02 +0200


> Le 12 sept. 2018 à 23:46, Frank Heckenbach <address@hidden> a écrit :
> 
> Hans Åberg wrote:
> 
>>>>>  Modern C++ (i.e., C++11 and later) introduced "move only" types: types 
>>>>> such
>>>>>  as std::unique_ptr<T> that can never be duplicated.  They must never be
>>>>>  copied (by assignments and constructors), they must be "moved".  The
>>>>>  implementation of lalr1.cc used to copy symbols (including their semantic
>>>>>  values).  This commit ensures that values are only moved in modern C++, 
>>>>> yet
>>>>>  remain compatible with C++98/C++03.
>>>> 
>>>> Hopefully copy only types can still be used. So say:
>>> 
>>> C++ will automatically copy when copy is available and move is not.
>> 
>> Yes, but strictly, that is not what the above text says.
> 
> Depends on your definitions. IMHO in (modern) C++ "move" always
> implies "copy" if possible and necessary, though I wouldn't object
> to spelling it out here.

So I went for what follows.

Should I consider this commit to be validated?  I don’t think
there will be more reviewers than you two guys :/




lalr1.cc: support move semantics

Modern C++ (i.e., C++11 and later) introduced "move only" types: types such
as std::unique_ptr<T> that can never be duplicated.  They must never be
copied (by assignments and constructors), they must be "moved".  The
implementation of lalr1.cc used to copy symbols (including their semantic
values).  This commit ensures that values are only moved in modern C++, yet
remain compatible with C++98/C++03.

Suggested by Frank Heckenbach, who provided a full implementation on
top of C++17's std::variant.
See http://lists.gnu.org/archive/html/bug-bison/2018-03/msg00002.html,
and https://lists.gnu.org/archive/html/bison-patches/2018-04/msg00002.html.

Symbols (terminal/non terminal) are handled by several functions that used
to take const-refs, which resulted eventually in a copy pushed on the stack.
With modern C++ (C++11 and later) the callers must use std::move, and the
callees must take their arguments as rvalue refs (foo&&).  In order to avoid
duplicating these functions to support both legacy C++ and modern C++, let's
introduce macros (YY_MOVE, YY_RVREF, etc.)  that rely on copy-semantics for
C++98/03, and move-semantics for modern C++.

That's easy for inner types, when the parser's functions pass arguments to
each other.  Funtions facing the user (make_NUMBER, make_STRING, etc.)
should support both rvalue-refs (for instance to support move-only types:
make_INT (std::make_unique<int> (1))), and lvalue-refs (so that we can pass
a variable: make_INT (my_int)).  To avoid the multiplication of the
signatures (there is also the location), let's take the argument by value.

See:
https://lists.gnu.org/archive/html/bison-patches/2018-09/msg00024.html.

* data/c++.m4 (b4_cxx_portability): New.
(basic_symbol): In C++11, replace copy-ctors with move-ctors.
In C++11, replace copies with moves.
* data/lalr1.cc (stack_symbol_type, yypush_): Likewise.
Use YY_MOVE to avoid useless copies.
* data/variant.hh (variant): Support move-semantics.
(make_SYMBOL): In C++11, in order to support both read-only lvalues,
and rvalues, take the argument as a copy.
* data/stack.hh (yypush_): Use rvalue-refs in C++11.
* tests/c++.at: Use move semantics.

* tests/headers.at: Adjust to the new macros (YY_MOVE, etc.).

* configure.ac (CXX98_CXXFLAGS, CXX11_CXXFLAGS, CXX14_CXXFLAGS)
(CXX17_CXXFLAGS, ENABLE_CXX11): New.
* tests/atlocal.in: Receive them.

* examples/variant.yy: Don't define things in std.
* examples/variant-11.test, examples/variant-11.yy: New.
Check the support of move-only types.
* examples/README, examples/local.mk: Adjust.




reply via email to

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