diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index d5692bf5..a36233f1 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -18,6 +18,13 @@ jobs: compiler_version: [g++-10, g++-11] cxx_std: [17, 20] os: [ubuntu-22.04] + disable_trace: [false] + include: + # Test with trace disabled + - compiler_version: g++-11 + cxx_std: 20 + os: ubuntu-22.04 + disable_trace: true runs-on: ${{ matrix.os }} @@ -30,7 +37,11 @@ jobs: run: | mkdir build cd build - cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }} + if [ "${{ matrix.disable_trace }}" = "true" ]; then + cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }} -DDISABLE_TRACE=true + else + cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }} + fi - name: Build run: cd build ; make -j4 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d40a5f8e..1a202bdc 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,6 +17,12 @@ jobs: matrix: cxx_std: [17, 20, 23] os: [windows-2022] + disable_trace: [false] + include: + # Test with trace disabled + - cxx_std: 20 + os: windows-2022 + disable_trace: true runs-on: ${{ matrix.os }} @@ -26,7 +32,13 @@ jobs: - name: Configure CMake # Configure CMake in a 'build' subdirectory. Visual Studio is a multi-config generator, so we don't use CMAKE_BUILD_TYPE. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B build -DCXX_STD=${{ matrix.cxx_std }} + run: | + if ("${{ matrix.disable_trace }}" -eq "true") { + cmake -B build -DCXX_STD=${{ matrix.cxx_std }} -DDISABLE_TRACE=true + } else { + cmake -B build -DCXX_STD=${{ matrix.cxx_std }} + } + shell: pwsh - name: Build working-directory: build diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d78d7a..115d0b30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,12 @@ if (BUILD_WITH_HANA) add_definitions(-DBOOST_PARSER_USE_HANA_TUPLE) endif() +set(DISABLE_TRACE false CACHE BOOL + "Disable parser trace functionality (defines BOOST_PARSER_DISABLE_TRACE).") +if (DISABLE_TRACE) + add_definitions(-DBOOST_PARSER_DISABLE_TRACE) +endif() + ################################################## # Dependencies diff --git a/doc/parser.qbk b/doc/parser.qbk index b6ab37d7..509ccf49 100644 --- a/doc/parser.qbk +++ b/doc/parser.qbk @@ -148,6 +148,7 @@ [def _RULES_ [macroref BOOST_PARSER_DEFINE_RULES `BOOST_PARSER_DEFINE_RULES`]] [def _AGGR_SIZE_ [macroref BOOST_PARSER_MAX_AGGREGATE_SIZE `BOOST_PARSER_MAX_AGGREGATE_SIZE`]] [def _SUBRNG_ [macroref BOOST_PARSER_SUBRANGE `BOOST_PARSER_SUBRANGE`]] +[def _DISABLE_TRACE_ [macroref BOOST_PARSER_DISABLE_TRACE `BOOST_PARSER_DISABLE_TRACE`]] [def __p_ [globalref boost::parser::_p `_p`]] diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk index aefc7cc0..efcf383b 100644 --- a/doc/tutorial.qbk +++ b/doc/tutorial.qbk @@ -3766,6 +3766,22 @@ Some things to be aware of when looking at _Parser_ trace output: produces that value. In these cases, you'll see the resolved value of the parse argument. +[heading Compile-time trace disabling] + +While trace mode is very useful for debugging, it does have some overhead. +Most parser templates are instantiated twice: Once with tracing enabled, +once with tracing disabled. +If you want to completely disable trace functionality at compile time, you can define +`BOOST_PARSER_DISABLE_TRACE` before including any Boost.Parser headers: + +[teletype]`` +#define BOOST_PARSER_DISABLE_TRACE +#include +`` + +When this define is set, all trace-related code is compiled out, +reducing the compile time. + [endsect] [section Memory Allocation] @@ -3983,7 +3999,8 @@ This defines a RAII trace object that will produce the verbose trace requested by the user if they passed `_trace_::on` to the top-level parse. It only has effect if `detail::enable_trace(flags)` is `true`. If trace is enabled, it will show the state of the parse at the point at which it is defined, and then -again when it goes out of scope. +again when it goes out of scope. By defining `BOOST_PARSER_DISABLE_TRACE`, +the trace feature can be disabled globally at compile time. [important For the tracing code to work, you must define an overload of `detail::print_parser` for your new parser type/template. See diff --git a/include/boost/parser/config.hpp b/include/boost/parser/config.hpp index 94067249..ff31295a 100644 --- a/include/boost/parser/config.hpp +++ b/include/boost/parser/config.hpp @@ -36,6 +36,10 @@ disable the use of concepts, define this macro. */ # define BOOST_PARSER_DISABLE_CONCEPTS +/** Boost.Parser will generate code to trace the execution of each and every + parser by default. To disable all trace code, define this macro. */ +# define BOOST_PARSER_DISABLE_TRACE + /** Define this macro to use `boost::hana::tuple` instead of `std::tuple` throughout Boost.Parser. */ # define BOOST_PARSER_USE_HANA_TUPLE @@ -92,6 +96,12 @@ # define BOOST_PARSER_USE_CONCEPTS 0 #endif +#if defined(BOOST_PARSER_DISABLE_TRACE) +# define BOOST_PARSER_DO_TRACE 0 +#else +# define BOOST_PARSER_DO_TRACE 1 +#endif + #if defined(__cpp_lib_ranges) && BOOST_PARSER_USE_CONCEPTS # define BOOST_PARSER_SUBRANGE std::ranges::subrange #else diff --git a/include/boost/parser/detail/printing.hpp b/include/boost/parser/detail/printing.hpp index e5dfe2f2..b8866f52 100644 --- a/include/boost/parser/detail/printing.hpp +++ b/include/boost/parser/detail/printing.hpp @@ -598,6 +598,9 @@ namespace boost { namespace parser { namespace detail { template auto resolve(Context const &, nope n); + template + constexpr bool trace_disabled = !DoTraceMacro; + template< bool DoTrace, typename Iter, @@ -606,6 +609,8 @@ namespace boost { namespace parser { namespace detail { typename Attribute> struct scoped_trace_t { + static_assert(!trace_disabled); + scoped_trace_t( std::ostream & os, Iter & first, @@ -681,6 +686,9 @@ namespace boost { namespace parser { namespace detail { flags f, Attribute const & attr) { + if constexpr (!BOOST_PARSER_DO_TRACE) + return; + if constexpr (Context::do_trace) { std::stringstream oss; detail::print_parser(context, parser, oss); @@ -695,6 +703,9 @@ namespace boost { namespace parser { namespace detail { template auto final_trace(Context const & context, flags f, Attribute const & attr) { + if constexpr (!BOOST_PARSER_DO_TRACE) + return; + if (!detail::do_trace(f)) return; diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index 947f152b..9b256abc 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -3180,6 +3180,7 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, @@ -3188,6 +3189,7 @@ namespace boost { namespace parser { detail::in_apply_parser(flags) ? detail::disable_trace(flags) : flags, retval); +#endif if constexpr (detail::is_optional_v) { detail::optional_type attr; @@ -3344,8 +3346,10 @@ namespace boost { namespace parser { Attribute & retval) const { //[ opt_parser_trace +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif //] //[ opt_parser_skip @@ -3508,8 +3512,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif use_parser_t const use_parser{ first, last, context, skip, flags, success}; @@ -3632,8 +3638,10 @@ namespace boost { namespace parser { decltype(detail::hl::transform(parsers_, use_parser)); result_t retval{}; +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first_, last, context, flags, retval); +#endif call_impl( first, @@ -3668,8 +3676,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first_, last, context, flags, retval); +#endif Iter first = first_; use_parser_t const use_parser{ @@ -4301,6 +4311,7 @@ namespace boost { namespace parser { std::decay_t(), llong<0>{}))> retval{}; +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first_, @@ -4309,6 +4320,7 @@ namespace boost { namespace parser { detail::in_apply_parser(flags) ? detail::disable_trace(flags) : flags, retval); +#endif std::decay_t(), llong<1>{}))> indices; @@ -4352,6 +4364,7 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first_, @@ -4360,6 +4373,7 @@ namespace boost { namespace parser { detail::in_apply_parser(flags) ? detail::disable_trace(flags) : flags, retval); +#endif Iter first = first_; @@ -4706,8 +4720,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto const initial_first = first; auto attr = parser_.call( @@ -4772,8 +4788,10 @@ namespace boost { namespace parser { detail::flags flags, bool & success) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, detail::global_nope); +#endif auto attr = parser_.call(first, last, context, skip, flags, success); if (success && detail::gen_attrs(flags)) @@ -4797,8 +4815,11 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif + auto attr = parser_.call(first, last, context, skip, flags, success); if (success && detail::gen_attrs(flags)) @@ -4825,8 +4846,10 @@ namespace boost { namespace parser { detail::flags flags, bool & success) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, detail::global_nope); +#endif parser_.call( first, @@ -4853,8 +4876,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif parser_.call( first, @@ -4904,8 +4929,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto const initial_first = first; parser_.call( @@ -4969,8 +4996,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto const initial_first = first; parser_.call( @@ -5045,8 +5074,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif parser_.call( first, @@ -5105,8 +5136,10 @@ namespace boost { namespace parser { auto context = context_; ++context.no_case_depth_; +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif parser_.call(first, last, context, skip, flags, success, retval); } @@ -5152,8 +5185,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if constexpr (detail::is_nope_v) { parser_.call( @@ -5216,8 +5251,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto first_copy = first; parser_.call( @@ -5383,8 +5420,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto [trie, _0] = detail::get_trie(context, ref()); auto const lookup = context.no_case_depth_ @@ -5458,8 +5497,10 @@ namespace boost { namespace parser { tag_type * const tag_ptr = nullptr; auto const rule_context = detail::make_rule_context( context, tag_ptr, retval, locals, params); +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, rule_context, flags, retval); +#endif bool dont_assign = false; if constexpr (in_recursion) { @@ -5556,8 +5597,10 @@ namespace boost { namespace parser { auto const rule_context = detail::make_rule_context( context, tag_ptr, attr, locals, params); +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, rule_context, flags, retval); +#endif bool dont_assign = false; parse_rule( @@ -6747,8 +6790,10 @@ namespace boost { namespace parser { detail::flags flags, bool & success) const noexcept { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, detail::global_nope); +#endif BOOST_PARSER_SUBRANGE const where(first, first); auto const predicate_context = detail::make_action_context( context, detail::global_nope, where); @@ -6775,8 +6820,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif BOOST_PARSER_SUBRANGE const where(first, first); auto const predicate_context = detail::make_action_context( context, detail::global_nope, where); @@ -6826,8 +6873,10 @@ namespace boost { namespace parser { detail::flags flags, bool & success) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, detail::global_nope); +#endif if (first != last) success = false; return {}; @@ -6848,8 +6897,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first != last) success = false; } @@ -6878,8 +6929,10 @@ namespace boost { namespace parser { detail::flags flags, bool &) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, detail::global_nope); +#endif return detail::resolve(context, attr_); } @@ -6898,8 +6951,10 @@ namespace boost { namespace parser { bool & success, Attribute_ & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (detail::gen_attrs(flags)) detail::assign_copy(retval, detail::resolve(context, attr_)); } @@ -6964,8 +7019,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7129,8 +7186,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7280,8 +7339,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7360,8 +7421,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7482,8 +7545,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7646,8 +7711,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -7967,8 +8034,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif if (first == last) { success = false; @@ -8134,8 +8203,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif auto compare = [no_case = context.no_case_depth_](char32_t a, char32_t b) { @@ -8223,8 +8294,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif T attr = 0; auto const initial = first; success = @@ -8364,8 +8437,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif T attr = 0; auto const initial = first; success = @@ -8479,8 +8554,10 @@ namespace boost { namespace parser { bool & success, Attribute & retval) const { +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif T attr = 0; auto const initial = first; success = detail::numeric::parse_real(first, last, attr); @@ -8573,8 +8650,10 @@ namespace boost { namespace parser { using attr_t = decltype(or_parser_.call( first, last, context, skip, flags, success)); attr_t attr{}; +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace(*this, first, last, context, flags, attr); +#endif attr = or_parser_.call(first, last, context, skip, flags, success); return attr; } @@ -8599,8 +8678,10 @@ namespace boost { namespace parser { "It looks like you tried to write switch_(val). You need at " "least one alternative, like: switch_(val)(value_1, " "parser_1)(value_2, parser_2)...")); +#if BOOST_PARSER_DO_TRACE [[maybe_unused]] auto _ = detail::scoped_trace( *this, first, last, context, flags, retval); +#endif or_parser_.call(first, last, context, skip, flags, success, retval); } @@ -9059,8 +9140,13 @@ namespace boost { namespace parser { "fill in attr above, using the attribute generated by parser. " "However, parser does not generate an attribute."); if (trace_mode == trace::on) { - return reset = detail::parse_impl( - first, last, parser, parser.error_handler_, attr); + return reset = + detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>( + first, + last, + parser, + parser.error_handler_, + attr); } else { return reset = detail::parse_impl( first, last, parser, parser.error_handler_, attr); @@ -9077,8 +9163,9 @@ namespace boost { namespace parser { "fill in attr above, using the attribute generated by parser. " "However, parser does not generate an attribute."); if (trace_mode == trace::on) { - return reset = detail::parse_impl( - f, l, parser, parser.error_handler_, attr); + return reset = + detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>( + f, l, parser, parser.error_handler_, attr); } else { return reset = detail::parse_impl( f, l, parser, parser.error_handler_, attr); @@ -9181,7 +9268,7 @@ namespace boost { namespace parser { { if constexpr (!detail::is_char8_iter_v) { if (trace_mode == trace::on) { - return detail::parse_impl( + return detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>( first, last, parser, parser.error_handler_); } else { return detail::parse_impl( @@ -9194,7 +9281,7 @@ namespace boost { namespace parser { auto const l = r.end(); auto _ = detail::scoped_base_assign(first, f); if (trace_mode == trace::on) { - return detail::parse_impl( + return detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>( f, l, parser, parser.error_handler_); } else { return detail::parse_impl( @@ -9300,7 +9387,8 @@ namespace boost { namespace parser { "fill in attr above, using the attribute generated by parser. " "However, parser does not generate an attribute."); if (trace_mode == trace::on) { - return reset = detail::skip_parse_impl( + return reset = detail::skip_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( first, last, parser, @@ -9328,7 +9416,8 @@ namespace boost { namespace parser { "fill in attr above, using the attribute generated by parser. " "However, parser does not generate an attribute."); if (trace_mode == trace::on) { - return reset = detail::skip_parse_impl( + return reset = detail::skip_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( f, l, parser, skip, parser.error_handler_, attr); } else { return reset = detail::skip_parse_impl( @@ -9433,7 +9522,7 @@ namespace boost { namespace parser { { if constexpr (!detail::is_char8_iter_v) { if (trace_mode == trace::on) { - return detail::skip_parse_impl( + return detail::skip_parse_impl<(true && BOOST_PARSER_DO_TRACE)>( first, last, parser, skip, parser.error_handler_); } else { return detail::skip_parse_impl( @@ -9446,7 +9535,7 @@ namespace boost { namespace parser { auto const l = r.end(); auto _ = detail::scoped_base_assign(first, f); if (trace_mode == trace::on) { - return detail::skip_parse_impl( + return detail::skip_parse_impl<(true && BOOST_PARSER_DO_TRACE)>( f, l, parser, skip, parser.error_handler_); } else { return detail::skip_parse_impl( @@ -9550,7 +9639,8 @@ namespace boost { namespace parser { { if constexpr (!detail::is_char8_iter_v) { if (trace_mode == trace::on) { - return detail::callback_parse_impl( + return detail::callback_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( first, last, parser, parser.error_handler_, callbacks); } else { return detail::callback_parse_impl( @@ -9563,7 +9653,8 @@ namespace boost { namespace parser { auto const l = r.end(); auto _ = detail::scoped_base_assign(first, f); if (trace_mode == trace::on) { - return detail::callback_parse_impl( + return detail::callback_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( f, l, parser, parser.error_handler_, callbacks); } else { return detail::callback_parse_impl( @@ -9675,7 +9766,8 @@ namespace boost { namespace parser { { if constexpr (!detail::is_char8_iter_v) { if (trace_mode == trace::on) { - return detail::callback_skip_parse_impl( + return detail::callback_skip_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( first, last, parser, @@ -9698,7 +9790,8 @@ namespace boost { namespace parser { auto const l = r.end(); auto _ = detail::scoped_base_assign(first, f); if (trace_mode == trace::on) { - return detail::callback_skip_parse_impl( + return detail::callback_skip_parse_impl<( + true && BOOST_PARSER_DO_TRACE)>( f, l, parser, skip, parser.error_handler_, callbacks); } else { return detail::callback_skip_parse_impl( diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index eebcf19d..75b074f1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -82,6 +82,7 @@ add_test_executable(parser_seq_permutations_1) add_test_executable(parser_seq_permutations_2) add_test_executable(parser_or_permutations_1) add_test_executable(parser_or_permutations_2) +add_test_executable(disable_trace) if (MSVC) add_executable(vs_output_tracing tracing.cpp) diff --git a/test/disable_trace.cpp b/test/disable_trace.cpp new file mode 100644 index 00000000..dd12a4c3 --- /dev/null +++ b/test/disable_trace.cpp @@ -0,0 +1,27 @@ +/** +* Copyright (C) 2025 + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_PARSER_DISABLE_TRACE + +#include +#include + +int main() +{ + namespace bp = boost::parser; + { + auto const parser = + bp::string("FOO") >> -(bp::string("bar") | bp::string("foo")); + + auto result = bp::parse("FOOfoo", parser); + BOOST_TEST(result); + BOOST_TEST(bp::get(*result, bp::llong<0>{}) == std::string("FOO")); + BOOST_TEST(bp::get(*result, bp::llong<1>{}) == std::string("foo")); + } + return boost::report_errors(); +} \ No newline at end of file