From 6ef788f8107c15c2fdc1158b2362de258af9f706 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 12 Nov 2018 18:35:21 +0100 Subject: [PATCH] C++: use noexcept and constexpr There are probably more opportunities for them. So far, I observed no performance improvements. * data/c++.m4, data/lalr1.cc, data/stack.hh: here. --- data/c++.m4 | 26 ++++++++++++++++++++------ data/lalr1.cc | 20 ++++++++++---------- data/stack.hh | 15 ++++++++++----- data/variant.hh | 14 +++++++------- tests/headers.at | 2 ++ 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/data/c++.m4 b/data/c++.m4 index 023f3736..3701525a 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -72,6 +72,20 @@ m4_define([b4_cxx_portability], # define YY_MOVE_REF(Type) Type& # define YY_RVREF(Type) const Type& # define YY_COPY(Type) const Type& +#endif + +// Support noexcept when possible. +#if 201103L <= YY_CPLUSPLUS +# define YY_NOEXCEPT noexcept +#else +# define YY_NOEXCEPT +#endif[]dnl + +// Support noexcept when possible. +#if 201703 <= YY_CPLUSPLUS +# define YY_CONSTEXPR constexpr +#else +# define YY_CONSTEXPR #endif[]dnl ]) @@ -266,7 +280,7 @@ m4_define([b4_symbol_type_declare], void clear (); /// Whether empty. - bool empty () const; + bool empty () const YY_NOEXCEPT; /// Destructive move, \a s is emptied into this. void move (basic_symbol& s); @@ -307,10 +321,10 @@ m4_define([b4_symbol_type_declare], /// The (internal) type number (corresponding to \a type). /// \a empty when empty. - symbol_number_type type_get () const; + symbol_number_type type_get () const YY_NOEXCEPT; /// The token. - token_type token () const; + token_type token () const YY_NOEXCEPT; /// The symbol type. /// \a empty_symbol when empty. @@ -402,7 +416,7 @@ m4_define([b4_public_types_define], template bool - ]b4_parser_class_name[::basic_symbol::empty () const + ]b4_parser_class_name[::basic_symbol::empty () const YY_NOEXCEPT { return Base::type_get () == empty_symbol; } @@ -445,13 +459,13 @@ m4_define([b4_public_types_define], } ]b4_inline([$1])[int - ]b4_parser_class_name[::by_type::type_get () const + ]b4_parser_class_name[::by_type::type_get () const YY_NOEXCEPT { return type; } ]b4_token_ctor_if([[ ]b4_inline([$1])b4_parser_class_name[::token_type - ]b4_parser_class_name[::by_type::token () const + ]b4_parser_class_name[::by_type::token () const YY_NOEXCEPT { // YYTOKNUM[NUM] -- (External) token number corresponding to the // (internal) symbol number NUM (which must be that of a token). */ diff --git a/data/lalr1.cc b/data/lalr1.cc index 78f3d1e0..89ebdcbc 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -296,26 +296,26 @@ m4_define([b4_shared_declarations], struct by_state { /// Default constructor. - by_state (); + by_state () YY_NOEXCEPT; /// The symbol type as needed by the constructor. typedef state_type kind_type; /// Constructor. - by_state (kind_type s); + by_state (kind_type s) YY_NOEXCEPT; /// Copy constructor. - by_state (const by_state& other); + by_state (const by_state& other) YY_NOEXCEPT; /// Record that this symbol is empty. - void clear (); + void clear () YY_NOEXCEPT; /// Steal the symbol type from \a that. void move (by_state& that); /// The (internal) type number (corresponding to \a state). /// \a empty_symbol when empty. - symbol_number_type type_get () const; + symbol_number_type type_get () const YY_NOEXCEPT; /// The state number used to denote an empty symbol. enum { empty_state = -1 }; @@ -570,16 +570,16 @@ m4_if(b4_prefix, [yy], [], ]b4_token_ctor_if([], [b4_public_types_define([cc])])[ // by_state. - ]b4_parser_class_name[::by_state::by_state () + ]b4_parser_class_name[::by_state::by_state () YY_NOEXCEPT : state (empty_state) {} - ]b4_parser_class_name[::by_state::by_state (const by_state& other) + ]b4_parser_class_name[::by_state::by_state (const by_state& other) YY_NOEXCEPT : state (other.state) {} void - ]b4_parser_class_name[::by_state::clear () + ]b4_parser_class_name[::by_state::clear () YY_NOEXCEPT { state = empty_state; } @@ -591,12 +591,12 @@ m4_if(b4_prefix, [yy], [], that.clear (); } - ]b4_parser_class_name[::by_state::by_state (state_type s) + ]b4_parser_class_name[::by_state::by_state (state_type s) YY_NOEXCEPT : state (s) {} ]b4_parser_class_name[::symbol_number_type - ]b4_parser_class_name[::by_state::type_get () const + ]b4_parser_class_name[::by_state::type_get () const YY_NOEXCEPT { if (state == empty_state) return empty_symbol; diff --git a/data/stack.hh b/data/stack.hh index 9ea5be15..4dc503c6 100644 --- a/data/stack.hh +++ b/data/stack.hh @@ -86,33 +86,38 @@ m4_define([b4_stack_define], operator[](0).move (t); } + /// Pop elements from the stack. void - pop (int n = 1) + pop (int n = 1) YY_NOEXCEPT { for (; 0 < n; --n) seq_.pop_back (); } + /// Pop all elements from the stack. void - clear () + clear () YY_NOEXCEPT { seq_.clear (); } + /// Number of elements on the stack. size_type - size () const + size () const YY_NOEXCEPT { return seq_.size (); } + /// Iterator on top of the stack (going downwards). const_iterator - begin () const + begin () const YY_NOEXCEPT { return seq_.rbegin (); } + /// Bottom of the stack. const_iterator - end () const + end () const YY_NOEXCEPT { return seq_.rend (); } diff --git a/data/variant.hh b/data/variant.hh index 2e0ac139..8a340f1a 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -94,7 +94,7 @@ m4_define([b4_variant_define], typedef variant self_type; /// Empty construction. - variant () + variant () YY_NOEXCEPT : yybuffer_ ()]b4_parse_assert_if([ , yytypeid_ (YY_NULLPTR)])[ {} @@ -109,7 +109,7 @@ m4_define([b4_variant_define], } /// Destruction, allowed only if empty. - ~variant () + ~variant () YY_NOEXCEPT {]b4_parse_assert_if([ YYASSERT (!yytypeid_); ])[} @@ -170,7 +170,7 @@ m4_define([b4_variant_define], /// Accessor to a built \a T. template T& - as () + as () YY_NOEXCEPT {]b4_parse_assert_if([ YYASSERT (yytypeid_); YYASSERT (*yytypeid_ == typeid (T)); @@ -181,7 +181,7 @@ m4_define([b4_variant_define], /// Const accessor to a built \a T (for %printer). template const T& - as () const + as () const YY_NOEXCEPT {]b4_parse_assert_if([ YYASSERT (yytypeid_); YYASSERT (*yytypeid_ == typeid (T)); @@ -199,7 +199,7 @@ m4_define([b4_variant_define], /// variant::move (). template void - swap (self_type& other) + swap (self_type& other) YY_NOEXCEPT {]b4_parse_assert_if([ YYASSERT (yytypeid_); YYASSERT (*yytypeid_ == *other.yytypeid_);])[ @@ -258,7 +258,7 @@ m4_define([b4_variant_define], /// Accessor to raw memory as \a T. template T* - yyas_ () + yyas_ () YY_NOEXCEPT { void *yyp = yybuffer_.yyraw; return static_cast (yyp); @@ -267,7 +267,7 @@ m4_define([b4_variant_define], /// Const accessor to raw memory as \a T. template const T* - yyas_ () const + yyas_ () const YY_NOEXCEPT { const void *yyp = yybuffer_.yyraw; return static_cast (yyp); diff --git a/tests/headers.at b/tests/headers.at index 39285ed9..50fab0cc 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -316,6 +316,7 @@ AT_CHECK([[$PERL -n -0777 -e ' |YYPUSH_MORE(?:_DEFINED)? |YYUSE |YY_ATTRIBUTE(?:_PURE|_UNUSED)? + |YY_CONSTEXPR |YY_COPY |YY_CPLUSPLUS |YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END) @@ -323,6 +324,7 @@ AT_CHECK([[$PERL -n -0777 -e ' |YY_MOVE |YY_MOVE_OR_COPY |YY_MOVE_REF + |YY_NOEXCEPT |YY_NULLPTR |YY_RVREF |YY_\w+_INCLUDED