Support constructor with an argument.

This improves the "list" bench by 2%.

	* data/lalr1.cc (variant::build): Add an overloaded version with
	an argument.
	* tests/c++.at (AT_CHECK_VARIANT): Check it.
This commit is contained in:
Akim Demaille
2008-08-08 00:38:07 +02:00
parent 763074102b
commit e5eb92e794
3 changed files with 38 additions and 11 deletions

View File

@@ -1,3 +1,12 @@
2008-11-10 Akim Demaille <demaille@gostai.com>
Support constructor with an argument.
This improves the "list" bench by 2%.
* data/lalr1.cc (variant::build): Add an overloaded version with
an argument.
* tests/c++.at (AT_CHECK_VARIANT): Check it.
2008-11-10 Akim Demaille <demaille@gostai.com> 2008-11-10 Akim Demaille <demaille@gostai.com>
Test variants. Test variants.

View File

@@ -247,6 +247,16 @@ dnl FIXME: This is wrong, we want computed header guards.
return *new (buffer) T; return *new (buffer) T;
} }
/// Instantiate a \a T in here from \a t.
template <typename T>
inline T&
build(const T& t)
{]b4_assert_if([
assert(!built);
built = true;])[
return *new (buffer) T(t);
}
/// Accessor to a built \a T. /// Accessor to a built \a T.
template <typename T> template <typename T>
inline T& inline T&

View File

@@ -33,6 +33,8 @@ AT_DATA([list.yy],
%skeleton "lalr1.cc" %skeleton "lalr1.cc"
%defines %defines
%define variant %define variant
]m4_bpatsubst([$1], [\\n], [
])[
%code requires // code for the .hh file %code requires // code for the .hh file
{ {
@@ -87,7 +89,7 @@ typedef std::list<std::string> strings_type;
%% %%
result: result:
list { std::cout << $][1; } list { std::cout << $][1; }
; ;
list: list:
@@ -111,19 +113,24 @@ yylex(yy::parser::semantic_type* yylval)
switch (stage) switch (stage)
{ {
case 0: case 0:
yylval->build<std::string>() = std::string("BEGIN"); case 4:
#ifdef ONE_STAGE_BUILD
yylval->build(string_cast(stage));
#else
yylval->build<std::string>() = string_cast(stage);
#endif
result = yy::parser::token::TEXT; result = yy::parser::token::TEXT;
break; break;
case 1: case 1:
case 2: case 2:
case 3: case 3:
#ifdef ONE_STAGE_BUILD
yylval->build(stage);
#else
yylval->build<int>() = stage; yylval->build<int>() = stage;
#endif
result = yy::parser::token::NUMBER; result = yy::parser::token::NUMBER;
break; break;
case 4:
yylval->build<std::string>() = std::string("END");
result = yy::parser::token::TEXT;
break;
default: default:
result = yy::parser::token::END_OF_FILE; result = yy::parser::token::END_OF_FILE;
break; break;
@@ -133,7 +140,6 @@ yylex(yy::parser::semantic_type* yylval)
return result; return result;
} }
// Mandatory error function
void void
yy::parser::error(const yy::parser::location_type& yylloc, yy::parser::error(const yy::parser::location_type& yylloc,
const std::string& message) const std::string& message)
@@ -141,7 +147,8 @@ yy::parser::error(const yy::parser::location_type& yylloc,
std::cerr << yylloc << ": " << message << std::endl; std::cerr << yylloc << ": " << message << std::endl;
} }
int main(int argc, char *argv[]) int
main(int argc, char *argv[])
{ {
yy::parser p; yy::parser p;
p.set_debug_level(!!getenv("YYDEBUG")); p.set_debug_level(!!getenv("YYDEBUG"));
@@ -149,14 +156,14 @@ int main(int argc, char *argv[])
} }
]]) ]])
AT_BISON_CHECK([-o list.cc list.yy], 0) AT_BISON_CHECK([-o list.cc list.yy])
AT_COMPILE_CXX([list]) AT_COMPILE_CXX([list])
AT_CHECK([./list], 0, AT_CHECK([./list], 0,
[BEGIN [0
1 1
2 2
3 3
END 4
]) ])
AT_CLEANUP AT_CLEANUP
@@ -164,6 +171,7 @@ AT_CLEANUP
AT_CHECK_VARIANTS([]) AT_CHECK_VARIANTS([])
AT_CHECK_VARIANTS([%define assert]) AT_CHECK_VARIANTS([%define assert])
AT_CHECK_VARIANTS([[%define assert %code {\n#define ONE_STAGE_BUILD\n}]])
## ----------------------- ## ## ----------------------- ##